You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito 4.8.0无法Mock构造方法:测试断言失败返回null

问题原因分析

你遇到的测试失败,核心是测试代码中手动创建的Author Mock实例,和控制器方法内部new Author()生成的实例是两个完全不同的对象。你给前者设置的方法返回值,无法作用到后者身上,所以控制器调用方法后返回默认的null。

解决方案

方案一:通过mockConstruction回调统一设置所有实例行为

利用mockConstruction的回调参数,在每个Author实例被创建时,直接定义其方法的返回逻辑,这样控制器内部创建的实例也会遵循这个行为:

@Test
public void testGetStringBuiltByComplexProcess01() {
    final String firstName = "firstName";
    final String lastName = "lastName";
    final String expectedResult = "when worked";

    try (MockedConstruction<Author> ignored = mockConstruction(Author.class,
            (mock, context) -> {
                // 对所有通过new创建的Author实例,统一设置方法返回值
                when(mock.methodWhichMakesNetworkAndDatabaseCalls(eq(firstName), eq(lastName)))
                        .thenReturn(expectedResult);
            })) {
        // 调用控制器方法
        String actualResult = ut.getStringBuiltByComplexProcess(firstName, lastName);
        
        // 断言结果
        assertEquals(expectedResult, actualResult, "Strings should match");
        
        // 获取控制器内部创建的实例,验证方法调用
        Author createdAuthor = ignored.constructed().get(0);
        verify(createdAuthor).methodWhichMakesNetworkAndDatabaseCalls(eq(firstName), eq(lastName));
    }
}

方案二:获取控制器内部创建的实例再配置行为

先触发控制器创建Author实例,再通过mockConstruction.constructed()拿到该实例,配置其方法行为后重新调用验证:

@Test
public void testGetStringBuiltByComplexProcess01() {
    final String firstName = "firstName";
    final String lastName = "lastName";
    final String expectedResult = "when worked";

    try (MockedConstruction<Author> mockConstruction = mockConstruction(Author.class)) {
        // 第一次调用,触发控制器内部创建Author实例
        ut.getStringBuiltByComplexProcess(firstName, lastName);
        
        // 获取控制器创建的那个Mock实例
        Author createdAuthor = mockConstruction.constructed().get(0);
        
        // 给该实例设置方法返回值
        when(createdAuthor.methodWhichMakesNetworkAndDatabaseCalls(eq(firstName), eq(lastName)))
                .thenReturn(expectedResult);
        
        // 第二次调用,验证返回值
        String actualResult = ut.getStringBuiltByComplexProcess(firstName, lastName);
        assertEquals(expectedResult, actualResult, "Strings should match");
        
        // 验证方法调用
        verify(createdAuthor).methodWhichMakesNetworkAndDatabaseCalls(eq(firstName), eq(lastName));
    }
}
关键注意点
  • mockConstruction的作用是拦截try代码块内所有new Author()的创建动作,返回Mock实例,但每次new都会生成一个独立的Mock对象。
  • 不要将测试代码中手动创建的Mock实例,和控制器内部生成的实例混淆,二者是不同的对象,配置不会互通。

内容的提问来源于stack exchange,提问作者Oxnard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 18:10:47