Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test logging in junit5?

I am transitioning from junit4 to junit5 on a project and trying to figure out how to test logs. Previously, I used

@Rule
OutputCapture outputCapture = new OutputCapture();

and would then write an assertion using outputCapture.toString(), for example

assertThat(outputCapture.toString(),containsString("status=200"));

Since @Rule annotation hasn't been implemented yet in junit5, I can't use outputCapture. Any ideas what to do instead? Thanks!

like image 839
ByteByByte Avatar asked Mar 13 '17 14:03

ByteByByte


People also ask

How do I test a logger message in JUnit?

@StefanoL: If a logger is defined with private static final Logger LOGGER = Logger. getLogger(someString); , you can still access it from unit tests with Logger. getLogger(someString); , modify it and add handlers (as in the accepted answer).

What is JUnit5 testing?

JUnit is one of the most popular unit-testing frameworks in the Java ecosystem. The JUnit 5 version contains a number of exciting innovations, with the goal of supporting new features in Java 8 and above, as well as enabling many different styles of testing.

Should you unit test logger?

Yes, we should test logging when the logging is doing something that is required. For example, you have hooks in some external application that scans the log for certain events. In that case you certainly want to ensure the logging is done.


3 Answers

There's an extension provided for the same and you can use it as below:

@ExtendWith(OutputCaptureExtension.class)
public class MyTestClass {

    @Test
    void myTestCase(CapturedOutput capturedOutput) {
        assertTrue(capturedOutput.getOut().contains("expected string"));
        assertTrue(capturedOutput.getErr().contains("expected string"));
    }
}
like image 116
VaibS Avatar answered Sep 27 '22 17:09

VaibS


You can also easily test the log output written to System.out by quickly implementing a solution on your own as follows:

// Configure System.out to be written to a buffer from which we can read
PrintStream realSysOut = System.out;
BufferedOutputStream sysOutBuffer = new ByteArrayOutputStream();
System.setOut(new PrintStream(sysOutBuffer));
...
// Perform some action which logs something to System.out
System.out.println("Some random content written to System.out");
...
// Assert that a given string was written in the meantime to System.out
assertThat(new String(buffer.toByteArray()), containsString("random content"));
...
// Don't forget to bring back the real System.out at the end of the test
System.setOut(realSysOut);

In the case of checking log output written to System.err, you can equivalently implement it by replacing System.setOut(...) with System.setErr(...) and System.out with System.err in the example above.

like image 34
Marko Previsic Avatar answered Sep 27 '22 19:09

Marko Previsic


We stumbled upon the same issue during our JUnit5 migration. After some research, I found a technical solution but it didn't seem like someone made a testing library out of it just yet. So that's what I did. It's published to Maven Central so you can use it right away:

https://github.com/netmikey/logunit

You can use it as follows:

public class MyModuleTest {

    @RegisterExtension
    LogCapturer logs = LogCapturer.create().captureForType(MyModule.class);

    @Test
    public void testLogging() {
        // ... do the testing ...

        // Run assertions on the logged messages
        logs.assertContains("Some message");
    }
}

(see the project's README for more examples)

like image 42
netmikey Avatar answered Sep 27 '22 18:09

netmikey