11

I am using java logging in my classes.

Example:

public class MyClass  {
    private static Logger logger = Logger.getLogger(MyClass.class.getName());
    ....
}

When I am writing a JUnit Test for that class, I would like to set the Loglevel to 'FINE'. I tried:

@Before
public void setup() throws PluginException {
    Logger.getGlobal().setLevel(Level.FINE);
    ....
}

But this has no effect. How can I control the loglevel in a JUnit Test when using Java Logging? I am running my tests using Maven.

Parker
  • 7,244
  • 12
  • 70
  • 92
Ralph
  • 4,500
  • 9
  • 48
  • 87

3 Answers3

8

This is the simplest, most generic way I've found to set the java.util.logging level for JUnit tests.

import java.util.logging.Level;
import java.util.logging.Logger;

import org.junit.BeforeClass;
import org.junit.Test;

public class MyTest
{
    @BeforeClass
    public static void beforeClass()
    {
        System.setProperty("java.util.logging.config.file", ClassLoader.getSystemResource("logging.properties").getPath());
    }

    @Test
    public void test00a()
    {
        Logger.getLogger(MyTest.class.getName()).log(Level.FINE, "J.U.L. test");
    }
}

In src/test/resources create logging.properties (.level must be the first line):

.level=FINEST
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST

When you run the unit test(s) in this class, you should see:

May 01, 2017 12:17:12 PM MyTest test00a

FINE: J.U.L. test

Community
  • 1
  • 1
Parker
  • 7,244
  • 12
  • 70
  • 92
1

Logger.getLogger() documentation:

Find or create a logger for a named subsystem. If a logger has already been created with the given name it is returned. Otherwise a new logger is created.

In your case, Logger.getLogger() with the same name gives you the same logger-instance. Therefore, you can get the logger and set its level with

@Before
public void setup() throws PluginException {
    Logger.getLogger(MyClass.class.getName()).setLevel(Level.FINE);
    ...
}

Just make sure to set it back in the @After-method later.

TMichelsen
  • 327
  • 1
  • 7
  • 3
    Thanks for your answer, but this did not work. Maybe I need to set also some additional global log level? I debugged the code and my class is now logging - but not into the standard output. I am running tests with Maven. – Ralph Jul 26 '16 at 12:51
  • @Ralph See [this answer](https://stackoverflow.com/a/43722641/2074605) for a complete example that works at the class level. – Parker Jul 05 '18 at 11:10
  • If you using SLF4J you will not be able to set the level. You can work around this by casting the logger to its underlying implementation. In my case that was Logback (Spring Boot's default). ``` @BeforeEach public void setup() { ch.qos.logback.classic.Logger logger = (Logger) org.slf4j.LoggerFactory.getLogger(MyClass.class.getName()); logger.setLevel(Level.TRACE); } ``` – Bampfer May 22 '23 at 13:18
0

To solve this problem, I defined a custom JUnit 4 rule to disable logs for a specific test:

@RequiredArgsConstructor
public class LogLevelRule extends TestWatcher {

  private Level oldLevel;
  private final Class clazz;
  private final String levelString;

  @Override
  protected void starting(Description description) {
    oldLevel = Logger.getLogger(clazz).getLevel();
    Logger.getLogger(clazz).setLevel(Level.toLevel(levelString));
  }

  @Override
  protected void finished(Description description) {
    Logger.getLogger(clazz).setLevel(oldLevel);
  }
}

This can then be enabled by declaring a @Rule of @ClassRule in the particular test:

  @ClassRule
  public static LogLevelRule logLevelRule = new LogLevelRule(MyClass.class, "OFF");
piepera
  • 2,033
  • 1
  • 20
  • 21