Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 373
shrini1000 Avatar asked May 24 '12 09:05

shrini1000


People also ask

Why do we use Logger instead of system out Println?

If you are running a Java program in Linux or any UNIX-based system, Log4j or SLF4j or any other logging framework offers a lot more features, flexibility, and improvement on message quality, which is not possible using the System. out. println() statement.

Where do we use logger in Java?

A Logger object is used to log messages for a specific system or application component. Loggers are normally named, using a hierarchical dot-separated namespace. Logger names can be arbitrary strings, but they should normally be based on the package name or class name of the logged component, such as java.net or javax.


2 Answers

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.

like image 88
Matthew Farwell Avatar answered Oct 24 '22 12:10

Matthew Farwell


I would not alter or extend the JUnit classes.

An arrangement where you try/catch and log errors would be preferable.

The problem is that failing an Assert is not necessarily an exception.

It feels like you're trying to make log4j into the reporting capability that already exists. I'd advise that you look into the Ant JUnit reporting task - it'll give you a nice looking report that will be more useful than a log.

UPDATE:

You can always add another log4j file appender. Let log4j write messages to both the console and the file that you choose. No changes in your code at all if I'm correct.

like image 20
duffymo Avatar answered Oct 24 '22 12:10

duffymo