Ideally, you don't use System output. You'd rather inject a logger and test against that.
But, it can still be done
// Store the original standard out before changing it.
private final PrintStream originalStdOut = System.out;
private ByteArrayOutputStream consoleContent = new ByteArrayOutputStream();
@BeforeMethod
public void beforeTest() {
// Redirect all System.out to consoleContent.
System.setOut(new PrintStream(this.consoleContent));
}
You may need to do something similar for System.err
for ex.printStackTrace()
output...
Then run your function in a standard test, and assert against the consoleContent
contents.
@Test
public void testFileExistence() {
doSomething("missing-file.txt"); // call a method of your service code that prints an exception
int n = this.consoleContent.available();
byte[] bytes = new byte[n];
this.consoleContent.read(bytes, 0, n);
String s = new String(bytes, StandardCharsets.UTF_8);
// TODO: split on line-breaks, and test printed content
}
After each test, you'll need to reset the stream, and if you still want to print the data, then do that too
@AfterMethod
public void afterTest() {
// Put back the standard out.
System.setOut(this.originalStdOut);
// Print what has been captured.
System.out.println(this.consoleContent.toString());
System.out.println(String.format(" ====>Captured Console length=%d",
this.consoleContent.toString().length()));
// Clear the consoleContent.
this.consoleContent = new ByteArrayOutputStream();
}
Or, more ideally, you define your own RuntimeException / Exception subclasses, then use assertThrows methods, where you can properly verify exception object content, including the message body.