Solución:
usar ByteArrayOutputStream y System.setXXX es simple:
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
private final PrintStream originalOut = System.out;
private final PrintStream originalErr = System.err;
@Before
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
}
@After
public void restoreStreams() {
System.setOut(originalOut);
System.setErr(originalErr);
}
casos de prueba de muestra:
@Test
public void out() {
System.out.print("hello");
assertEquals("hello", outContent.toString());
}
@Test
public void err() {
System.err.print("hello again");
assertEquals("hello again", errContent.toString());
}
Usé este código para probar la opción de línea de comando (afirmando que -version genera la cadena de versión, etc., etc.)
Editar:
Versiones anteriores de esta respuesta llamadas System.setOut(null)
después de las pruebas; Esta es la causa de las NullPointerExceptions a las que hacen referencia los comentaristas.
Sé que este es un hilo antiguo, pero hay una buena biblioteca para hacer esto:
Reglas del sistema
Ejemplo de los documentos:
public void MyTest {
@Rule
public final SystemOutRule systemOutRule = new SystemOutRule().enableLog();
@Test
public void overrideProperty() {
System.out.print("hello world");
assertEquals("hello world", systemOutRule.getLog());
}
}
También te permitirá atrapar System.exit(-1)
y otras cosas para las que debería probarse una herramienta de línea de comandos.
En lugar de redirigir System.out
, Refactorizaría la clase que usa System.out.println()
pasando un PrintStream
como colaborador y luego usando System.out
en producción y un Espía de prueba en la prueba. Es decir, utilice la inyección de dependencia para eliminar el uso directo del flujo de salida estándar.
En producción
ConsoleWriter writer = new ConsoleWriter(System.out));
En la prueba
ByteArrayOutputStream outSpy = new ByteArrayOutputStream();
ConsoleWriter writer = new ConsoleWriter(new PrintStream(outSpy));
writer.printSomething();
assertThat(outSpy.toString(), is("expected output"));
Discusión
De esta manera, la clase bajo prueba se puede probar mediante una simple refactorización, sin tener la necesidad de una redirección indirecta de la salida estándar o una interceptación oscura con una regla del sistema.