首页 > 解决方案 > 单元测试中的 Mocking Appender 需要创建实例吗?

问题描述

我有一些使用 mockito 和 junit 的工作单元测试来检查预期的日志条目。

沿着这些方向

@Mock
private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>();

@Before
public void setup() {
    Logger logger = (Logger) LoggerFactory.getLogger( MyClass.class );
    logger.addAppender( listAppender );
}

@Test
public void test1() {
    ...

    // then
    verifyZeroInteractions( mockAppender );
}

@Test
public void test2() {
    ...

    // then
    verify( listAppender ).doAppend( ArgumentMatchers.argThat( argument -> {
        assertThat( argument.getMessage(), containsString( "Expected Message." ) );
        assertThat( argument.getLevel(), is( Level.ERROR ) );
        return true;
    } ) );
}

这一切都很好,而且效果很好。

尽管我不理解 Appender 声明,但它暴露了我对 Mocking 框架的理解的弱点

@Mock
private final ListAppender<ILoggingEvent> listAppender = new ListAppender<>(); 

如果我删除 @Mock 注释,那么测试将停止工作,因为我无法验证 - org.mockito.exceptions.misusing.NotAMockException: Argument(s) passed is not a mock!

但如果它是一个模拟,我为什么要创建一个新实例?

如果我删除初始化

@Mock
private final ListAppender<ILoggingEvent> mockAppender;

我收到构建错误

java:变量mockAppender未在默认构造函数中初始化

标签: javaunit-testingmockito

解决方案


不应为模拟分配一个值,因为这是由 Mockito 执行的。但是 Mockito 没有在默认构造函数中设置值(因为它不能),所以它使用反射来设置它。因此,mockAppender 不能是最终的。

所以,你应该删除赋值和final,所以你的声明应该是这样的:

@Mock
private ListAppender<ILoggingEvent> mockAppender;

推荐阅读