13

I am writing some code for a programming contest in java. The input to the program is given using stdin and output is on stdout. How are you folks testing programs that work on stdin/stdout? This is what I am thinking:

Since System.in is of type InputStream and System.out is of type PrintStream, I wrote my code in a func with this prototype:

void printAverage(InputStream in, PrintStream out)

Now, I would like to test this using junit. I would like to fake the System.in using a String and receive the output in a String.

@Test
void testPrintAverage() {

    String input="10 20 30";
    String expectedOutput="20";

    InputStream in = getInputStreamFromString(input);
    PrintStream out = getPrintStreamForString();

    printAverage(in, out);

    assertEquals(expectedOutput, out.toString());
}

What is the 'correct' way to implement getInputStreamFromString() and getPrintStreamForString()?

Am I making this more complicated than it needs to be?

user674669
  • 10,681
  • 15
  • 72
  • 105
  • 1
    Maybe http://stackoverflow.com/questions/782178/how-do-i-convert-a-string-to-an-inputstream-in-java and http://stackoverflow.com/questions/216894/get-an-outputstream-into-a-string can help... – tcovo Nov 11 '12 at 07:14
  • possible duplicate of [JUnit testing with simulated user input](http://stackoverflow.com/questions/6415728/junit-testing-with-simulated-user-input) – Jeff Bowman Apr 29 '14 at 03:12

3 Answers3

7

Try the following:

String string = "aaa";
InputStream stringStream = new java.io.ByteArrayInputStream(string.getBytes())

stringStream is a stream that will read chars from the input string.

OutputStream outputStream = new java.io.ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream);
// .. writes to printWriter and flush() at the end.
String result = outputStream.toString()

printStream is a PrintStream that will write to the outputStream which in turn will be able to return a string.

das-g
  • 9,718
  • 4
  • 38
  • 80
Mihai Toader
  • 12,041
  • 1
  • 29
  • 33
0

EDITED: Sorry I misread your question.

Read with scanner or bufferedreader, The latter is much faster than the former.

Scanner jin = new Scanner(System.in);

BufferedReader reader = new BufferedReader(System.in);

Write to stdout with print writer. You can also print directly to Syso but this is slower.

System.out.println("Sample");
System.out.printf("%.2f",5.123);

PrintWriter out = new PrintWriter(System.out);
out.print("Sample");
out.close();
Willem
  • 376
  • 2
  • 8
  • You can't pass `System.in` into a BufferedReader. You need to wrap it in an `InputStreamReader` first. – byxor Dec 14 '16 at 11:35
0

I am writing some code for a programming contest in java. The input to the program is given using stdin and output is on stdout. How are you folks testing programs that work on stdin/stdout?

Another way to send characters to System.in is to use PipedInputStream and PipedOutputStream. Maybe something like the following:

PipedInputStream pipeIn = new PipedInputStream(1024);
System.setIn(pipeIn);

PipedOutputStream pipeOut = new PipedOutputStream(pipeIn);

// then I can write to the pipe
pipeOut.write(new byte[] { ... });

// if I need a writer I do:
Writer writer = OutputStreamWriter(pipeOut);
writer.write("some string");

// call code that reads from System.in
processInput();

On the flip side, as mentioned by @Mihai Toader, if I need to test System.out then I do something like:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.setOut(new PrintStream(baos));

// call code that prints to System.out
printSomeOutput();

// now interrogate the byte[] inside of baos
byte[] outputBytes = baos.toByteArray();
// if I need it as a string I do
String outputStr = baos.toString();

Assert.assertTrue(outputStr.contains("some important output"));
Gray
  • 115,027
  • 24
  • 293
  • 354