使用 @Slf4j 注释创建时如何模拟 Logger?
How to mock Logger when created with the @Slf4j annotation?
我有一个带有@Slf4j 注释的class。
我尝试编写测试并模拟 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.
问题是,如何模拟记录器?
lombok @Slf4j
注释在编译时 class 注入代码 。具体来说,它会将以下代码添加到您的 class:
private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger(LogExample.class);
@InjectMocks
告诉 Mockito 创建您的 class 的一个实例,并在运行时 作为其依赖项注入模拟 。
记录器是在编译时注入的。依赖项在运行时注入。这就是为什么您的记录器没有被嘲笑并且不能像这样被嘲笑的原因。如果您查看上面注入的记录器代码,您就会明白,模拟记录器的唯一方法是模拟 LoggerFactory(Mockito 可以模拟自 3.4 版以来的静态方法,IIRC)并使其 return 模拟记录器.
注意:制作模拟 return 模拟通常是一个坏主意,应该避免。 @Slf4j
太方便了不能用。这是一个权衡。
注意:如果您只想让记录器静音,那么您也可以将其配置为在测试中关闭。
您可以使用 https://www.simplify4u.org/slf4j-mock/ 库。
您的示例代码将起作用 - 您只需要 slf4j-mock
依赖项而不是其他 slf4j
绑定。
我有一个带有@Slf4j 注释的class。
我尝试编写测试并模拟 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.
问题是,如何模拟记录器?
lombok @Slf4j
注释在编译时 class 注入代码 。具体来说,它会将以下代码添加到您的 class:
private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger(LogExample.class);
@InjectMocks
告诉 Mockito 创建您的 class 的一个实例,并在运行时 作为其依赖项注入模拟 。
记录器是在编译时注入的。依赖项在运行时注入。这就是为什么您的记录器没有被嘲笑并且不能像这样被嘲笑的原因。如果您查看上面注入的记录器代码,您就会明白,模拟记录器的唯一方法是模拟 LoggerFactory(Mockito 可以模拟自 3.4 版以来的静态方法,IIRC)并使其 return 模拟记录器.
注意:制作模拟 return 模拟通常是一个坏主意,应该避免。 @Slf4j
太方便了不能用。这是一个权衡。
注意:如果您只想让记录器静音,那么您也可以将其配置为在测试中关闭。
您可以使用 https://www.simplify4u.org/slf4j-mock/ 库。
您的示例代码将起作用 - 您只需要 slf4j-mock
依赖项而不是其他 slf4j
绑定。