如何忽略/模拟 Slf4j 日志行?

问题描述 投票:0回答:1

我将 Spring Boot 从 2.5.10 升级到 2.5.12,它在 logback 中给我带来了重大变化 https://github.com/spring-projects/spring-boot/releases/tag/v2.5.11

我的一些单元测试(使用 Mockito)出现了 NullPointerException,其中我将模拟异常传递给主代码中的日志行。 例如,这是我的主代码中的日志行,该类用 lombok 的 @Slf4j

进行注释
log.warn("Exception occurred while doing something", exception);

之前,此日志行没有抛出任何错误。

我的目的是不模拟记录器,而是通过任何可能的解决方法忽略这一行(即使我必须模拟它)。

Lombok 在编译中添加了以下内容(不确定模拟是否可以在这里工作):

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(HelloWorld.class);

我的一个解决方法是不使用模拟异常并传递实际异常,但这会消除单元测试的乐趣。

堆栈跟踪:

java.lang.NullPointerException
    at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:99)
    at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:62)
    at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
    at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
    at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
    at ch.qos.logback.classic.Logger.warn(Logger.java:692)
    at com.example.r.e.d.s.d.t.HelloWorld.executeInternal(HelloWorld.java:74)
    at com.example.r.e.d.s.d.t.HelloWorldTest.testLocksOnDomain(HelloWorldTest.java:94)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:54)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:99)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:105)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:40)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)


Process finished with exit code 255

此外,我的单元测试使用以前的库版本。有一个问题是在执行单元测试期间,它常常在控制台中打印诸如 WARN 和 ERROR 之类的日志(有时会造成很多混乱)。

java unit-testing mockito logback slf4j
1个回答
3
投票

导致错误的行(在您提到的版本中)如下所示(请参阅https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java /ch/qos/logback/classic/spi/ThrowableProxy.java#L99):

if (throwableSuppressed.length > 0) {

值得注意的是,您的问题已得到解决,尽管我不知道现在或将来哪个版本的 Logback 可能有它。 https://github.com/qos-ch/logback/commit/c34645b320d2b31ccaf0de9bb079391904352a28包含以下相关更改: 已更换

if (throwableSuppressed.length > 0) {

// while JDK's implementation of getSuppressed() will always return a non-null array,
// this might not be the case in mocked throwables. We are being extra defensive here.
if (OptionHelper.isNotEmtpy(throwableSuppressed)) {

我自己一般不太热衷于模拟异常。但如果这就是您的上下文所要求的,那么模拟 getSuppressed() 返回一个非空(可能为空就可以了)数组可能会解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.