使用@Slf4j注解创建Logger时如何模拟Logger?

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

我有一个带有 @Slf4j 注释的类。

我尝试编写一个测试并模拟 Logger,但它不起作用。

@RequiredArgsConstructor
@Slf4j
public abstract class ExampleClass {
    
    protected final PropsClass properties;
    
    protected void logInfo(..) {
        log.info(...);
        clearMappedDiagnosticContext();
    }
}

这就是测试的样子:

@RunWith(MockitoJUnitRunner.class)
public class ExampleClassTest {
    
    @Mock
    Logger logger;
    
    @Mock
    PropsClass properties;
    
    @InjectMocks
    ExampleClass exampleClass;
    
    @Test
    public void logSomethingtest() {
        ...
        exampleClass.logInfo(...);
        Mockito.verify(logger).info(marker, "foo bar {}", ...);
    }

这是我得到的错误:

Wanted but not invoked:
logger.info(
    MY_MARKER,
    "..........",
    "....",
    "....",
    0L
);

Actually, there were zero interactions with this mock.

问题是,如何模拟Logger?

java unit-testing junit mockito slf4j
4个回答
12
投票

lombok

@Slf4j
注释将代码注入到您的类中在编译时。具体来说,它会将以下代码添加到您的类中:

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

@InjectMocks
告诉 Mockito 创建类的实例并在运行时注入模拟作为其依赖项

记录器在编译时注入。依赖项是在运行时注入的。这就是为什么你的记录器没有被嘲笑,也不能像这样被嘲笑。如果您查看上面注入的记录器代码,您就会明白,模拟记录器的唯一方法是模拟 LoggerFactory(Mockito 从 3.4 版本开始可以模拟静态方法,IIRC)并使其返回记录器模拟。

注意:让模拟返回模拟通常是一个坏主意,应该避免。

@Slf4j

太方便了,不敢用。这是一个权衡。

注意:如果您希望它使记录器静音,那么您也可以将其配置为在测试中关闭。


2
投票
由于 Mockito 还能够模拟静态方法,因为版本 3.4.0 也能够模拟静态方法,因此您可以简单地存根对记录器的访问,如下所示:

@Test void logmessageInCaseOfPositiveValidationIsWritten() { Logger mockedLogger = Mockito.mock(Logger.class); try (MockedStatic<LoggerFactory> context = Mockito.mockStatic(LoggerFactory.class)) { context.when(() -> LoggerFactory.getLogger(Mockito.any(Class.class))) .thenReturn(mockedLogger); // Your test code and your assertions Mockito.verify(mockedLogger) .debug("I am the expected message with param {}", "paramvalue"); } }
不要忘记使用下面的上下文创建所需的文件

test/resources/mockito-extensions/org.mockito.plugins.MockMaker

以启用静态模拟:

mock-maker-inline

为 Mockito 4.5.1 版本编写。


1
投票
您可以使用

https://www.simplify4u.org/slf4j-mock/库。

您的示例代码将起作用 - 您只需要

slf4j-mock

 依赖项而不是其他 
slf4j
 绑定。


0
投票
排除 slf4j 的问题是,您在应用程序上下文中不会有任何提供者

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