首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何通过JUnit测试拦截SLF4J (带logback)日志?

如何通过JUnit测试拦截SLF4J (带logback)日志?
EN

Stack Overflow用户
提问于 2015-03-16 20:36:21
回答 7查看 89.1K关注 0票数 98

有没有可能以某种方式截取日志记录(SLF4J + logback),并通过JUnit测试用例获得InputStream (或其他可读内容)...?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2015-03-16 21:02:12

您可以创建自定义附加器

public class TestAppender extends AppenderBase<LoggingEvent> {
    static List<LoggingEvent> events = new ArrayList<>();
    
    @Override
    protected void append(LoggingEvent e) {
        events.add(e);
    }
}

并配置logback-test.xml以使用它。现在,我们可以检查测试中的日志记录事件:

@Test
public void test() {
    ...
    Assert.assertEquals(1, TestAppender.events.size());
    ...
}

注意:如果您没有得到任何输出,请使用ILoggingEvent -有关原因,请参阅注释部分。

票数 46
EN

Stack Overflow用户

发布于 2018-09-08 05:06:13

Logback没有提供这样的方法,但是Slf4j提供了一个简单的解决方案。

您可以使用ListAppender:一个白盒logback附加器,其中日志条目被添加到public List字段中,我们可以使用该字段来进行断言。

这里有一个简单的例子。

Foo类:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Foo {

    static final Logger LOGGER = LoggerFactory.getLogger(Foo .class);

    public void doThat() {
        logger.info("start");
        //...
        logger.info("finish");
    }
}

FooTest类:

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;

public class FooTest {

    @Test
    void doThat() throws Exception {
        // get Logback Logger 
        Logger fooLogger = (Logger) LoggerFactory.getLogger(Foo.class);

        // create and start a ListAppender
        ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
        listAppender.start();

        // add the appender to the logger
        fooLogger.addAppender(listAppender);

        // call method under test
        Foo foo = new Foo();
        foo.doThat();

        // JUnit assertions
        List<ILoggingEvent> logsList = listAppender.list;
        assertEquals("start", logsList.get(0)
                                      .getMessage());
        assertEquals(Level.INFO, logsList.get(0)
                                         .getLevel());

        assertEquals("finish", logsList.get(1)
                                       .getMessage());
        assertEquals(Level.INFO, logsList.get(1)
                                         .getLevel());
    }
}

您还可以使用匹配器/断言库作为AssertJ或Hamcrest。

对于AssertJ,它将是:

import org.assertj.core.api.Assertions;

Assertions.assertThat(listAppender.list)
          .extracting(ILoggingEvent::getFormattedMessage, ILoggingEvent::getLevel)
          .containsExactly(Tuple.tuple("start", Level.INFO), Tuple.tuple("finish", Level.INFO));
票数 104
EN

Stack Overflow用户

发布于 2016-03-02 05:29:12

您可以从http://projects.lidalia.org.uk/slf4j-test/使用slf4j-test。它将整个logback实现替换为用于测试的自己的logback实现,并提供了一个针对日志事件进行断言的slf4j。

示例:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <configuration>
        <classpathDependencyExcludes>
          <classpathDependencyExcludes>ch.qos.logback:logback-classic</classpathDependencyExcludes>
        </classpathDependencyExcludes>
      </configuration>
    </plugin>
  </plugins>
</build>

public class Slf4jUser {

    private static final Logger logger = LoggerFactory.getLogger(Slf4jUser.class);

    public void aMethodThatLogs() {
        logger.info("Hello World!");
    }
}

public class Slf4jUserTest {

    Slf4jUser slf4jUser = new Slf4jUser();
    TestLogger logger = TestLoggerFactory.getTestLogger(Slf4jUser.class);

    @Test
    public void aMethodThatLogsLogsAsExpected() {
        slf4jUser.aMethodThatLogs();

        assertThat(logger.getLoggingEvents(), is(asList(info("Hello World!"))));
    }

    @After
    public void clearLoggers() {
        TestLoggerFactory.clear();
    }
}
票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29076981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档