Jav*_*mae 37 unit-testing mocking slf4j mockito
我正在使用slf4j,我想对我的代码进行单元测试,以确保在某些条件下生成警告/错误日志消息.我宁愿这些是严格的单元测试,所以我不想从文件中提取日志配置以测试日志消息的生成.我正在使用的模拟框架是Mockito.
eak*_*st7 18
为了在不依赖于特定实现(例如log4j)的情况下测试slf4j,您可以提供自己的slf4j日志记录实现,如本SLF4J FAQ中所述.您的实现可以记录已记录的消息,然后由单元测试进行查询以进行验证.
该SLF4J测试包正是这样做的.它是一个内存中的slf4j日志记录实现,它提供了检索记录消息的方法.
Zso*_*olt 12
我认为您可以使用自定义appender解决您的问题.创建一个测试appender来实现org.apache.log4j.Appender
,并在log4j.properties
执行测试用例时设置你的appender 并加载它.
如果从中回调测试线束,则appender
可以检查记录的消息
And*_*eng 10
创建测试规则:
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
public class LoggerRule implements TestRule {
private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
private final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
setup();
base.evaluate();
teardown();
}
};
}
private void setup() {
logger.addAppender(listAppender);
listAppender.start();
}
private void teardown() {
listAppender.stop();
listAppender.list.clear();
logger.detachAppender(listAppender);
}
public List<String> getMessages() {
return listAppender.list.stream().map(e -> e.getMessage()).collect(Collectors.toList());
}
public List<String> getFormattedMessages() {
return listAppender.list.stream().map(e -> e.getFormattedMessage()).collect(Collectors.toList());
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它:
@Rule
public final LoggerRule loggerRule = new LoggerRule();
@Test
public void yourTest() {
// ...
assertThat(loggerRule.getFormattedMessages().size()).isEqualTo(2);
}
Run Code Online (Sandbox Code Playgroud)
小智 9
SLF4J的更好的测试实现在并发测试执行的环境中非常有效,这是https://github.com/portingle/slf4jtesting
在谈到并发测试执行时,我已经讨论了一些关于slf4j日志测试的讨论以及现有测试方法的局限性.
我决定把我的话放到代码中,git repo就是结果.
您可以将需要测试的重要日志记录调用放在它们自己的方法中,而不是模拟 SLF4J,您可以更轻松地模拟这些方法。
如果您确实想模拟 SLF4J,我敢打赌您可以为其创建自己的提供程序,该提供程序将允许您从 SLF4J 端提供模拟记录器,而不是在服务对象中注入一个记录器。
小智 5
对于 JUnit 5,创建一个扩展来实现上面创建测试规则中由andrew-feng提供的解决方案:
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
public class LoggerExtension implements BeforeEachCallback, AfterEachCallback {
private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
private final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
listAppender.stop();
listAppender.list.clear();
logger.detachAppender(listAppender);
}
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
logger.addAppender(listAppender);
listAppender.start();
}
public List<String> getMessages() {
return listAppender.list.stream().map(e -> e.getMessage()).collect(Collectors.toList());
}
public List<String> getFormattedMessages() {
return listAppender.list.stream().map(e -> e.getFormattedMessage()).collect(Collectors.toList());
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它:
@RegisterExtension
public LoggerExtension loggerExtension = new LoggerExtension();
@Test
public void yourTest() {
// ...
assertThat(loggerExtension.getFormattedMessages().size()).isEqualTo(2);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31785 次 |
最近记录: |