You can configure System
with an instance of PrintStream
which you can then assert against after invoking Calculation.logTimeTaken
.
Here's an example:
@Test
public void canLogTimeTaken() {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
PrintStream out = new PrintStream(bout);
System.setOut(out);
Calculation sut = new Calculation();
sut.logTimeTaken("label", 20 , 2, false);
assertEquals("if isDebug is false label took 0 milliseconds for 2 events!\n", bout.toString());
}
Note: there is no need for Mockito here, this is just vanilla JUnit, no mocking.
But, it might be a better design to refactor logTimeTaken
into two distinct aspects:
- Deriving the log message
- Logging that message
For example:
public String createTimeTakenMessage(String label, long estimatedTime, int size, boolean isDebug) {
return label + " took " + TimeUnit.MILLISECONDS.convert(estimatedTime, TimeUnit.NANOSECONDS) + " milliseconds for " + size + " events!";
}
public void logTimeTaken(String message) {
System.out.println(message);
}
Then testing createTimeTakenMessage
is trivial and you might even choose not to test logTimeTaken
at all since all it does is invoke a System method. Or, perhaps you would hide the 'log action' behind an interface with an implementation using System.out
now and perhaps, later, other implementations using a formal logging framework such as Logback.