Search code examples
javaloggingjunitassert

Java: using a logger in JUnit assert*


What I want to do is something like the following in JUnit:

assertTrue(logger.error("the condition is not true"), <a boolean condition>);

so the error message gets logged by a logger, where the logger could be e.g. commons or log4j.

But Junit asserts don't take a logger param, so is there some way to achieve this, or do I need to try-catch the assert and log the error message in catch block?


Solution

  • You can use a JUnit TestRule TestWatcher. A TestRule executes code before and after the test method (similar to @Before and @After), but you have access to more information, and more importantly, the result of the test. A TestWatcher defines methods like succeeded(), failed(), starting() and finished(), which you can implement to get notified of events.

    The following example simply prints out the failed tests with the failed assertions.

    public class TestWatcherTest {
      @Rule
      public TestWatcher testWatcher = new TestWatcher() {
        protected void failed(Throwable e, Description description) {
          System.out.println("" + description.getDisplayName() + " failed " + e.getMessage());
          super.failed(e, description);
        }
    
      };
    
      @Test
      public void test1() {
        Assert.assertEquals("hello world", 3, 4);
      }
    }
    

    You can obviously do what you like instead of the System.out.println(). This produces as output:

    test1(uk.co.farwell.junit.TestWatcherTest) failed hello world expected:<3> but was:<4>
    

    Note that a failed assertion is an exception, so you'll have access to the stacktrace etc.