How to test what an application writes to the console

Submitted by kofa on Wed, 03/28/2012 - 13:34

Suppose you have to unit-test some Java code that writes to the console. Here's a way to do it:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;

public class StringPrintStream extends PrintStream {
	private final File file;
	public StringPrintStream() throws IOException {
		this(File.createTempFile("stringoutput", null));
	}
	private StringPrintStream(File f) throws IOException {
		super(f);
		file = f;
	}

	@Override
	public String toString() {
		flush();
		StringBuilder string = new StringBuilder();
		try {
			BufferedReader reader = new BufferedReader(new FileReader(file));
			while (reader.ready()) {
				string.append(reader.readLine());
			}
			reader.close();
		} catch (IOException e) {
			string.append("\n").append(e.getMessage());
		}
		return string.toString();
	}

	@Override
	public void close() {
		super.close();
		file.delete();
	}
}

In the test class:

public class SomeTest {
	@Before
	public void redirectOutput() throws IOException {
		stringPrinter = new StringPrintStream();
		System.setOut(stringPrinter);
	}

	@After
	public void restoreOutput() throws IOException {
		FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
		System.setOut(new PrintStream(new BufferedOutputStream(fdOut, 128),
				true));
		stringPrinter.close();
	}

	@Test
	public void testWhatever() {
		objectUnderTest.invokePrintingMethod();
		String output = stringPrinter.toString();
		assertEquals("Captured output", output);
	}
}