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

JUnit测试报错:DictionaryServiceTest.testAddDictionary预期对象却返回null

排查JUnit测试testAddDictionary返回null的原因及解决方法

你遇到的这个问题,核心是Mockito Mock对象的默认行为导致的,我来帮你拆解具体原因和对应的解决办法:

核心原因:Mock对象未配置方法返回值

当你用@MockBean注解创建DictionaryService的实例时,Mockito会生成一个代理Mock对象——这个对象的所有方法调用,默认都会返回对应类型的默认值:对象类型返回null,基本类型返回0/false等。所以你调用dictionaryService.addDictionary(...)时,自然会得到null,和预期的Dictionary对象不符。


解决办法分两种场景:

场景1:只是想验证Service方法的调用逻辑(比如是否被调用、调用参数)

如果你的测试目标是确认addDictionary方法被正确调用,而不是验证业务逻辑,那只需要给Mock的Service配置返回值即可:

@Test
public void testAddDictionary() {
    // 1. 构建你预期返回的Dictionary对象
    Dictionary expectedDict = new Dictionary();
    // 给对象设置必要属性,比如id、name等
    expectedDict.setId(1L);
    expectedDict.setName("TestDict");

    // 2. 指定Mock的Service调用addDictionary时返回预期对象
    // any(Dictionary.class)表示匹配任意Dictionary类型的参数
    when(dictionaryService.addDictionary(any(Dictionary.class))).thenReturn(expectedDict);

    // 3. 执行测试方法
    Dictionary testInput = new Dictionary();
    testInput.setName("TestDict");
    Dictionary actualDict = dictionaryService.addDictionary(testInput);

    // 4. 断言结果
    assertEquals(expectedDict, actualDict);
    // 还可以验证方法是否被调用
    verify(dictionaryService, times(1)).addDictionary(testInput);
}

场景2:想验证Service的真实业务逻辑(比如参数处理、Repo交互)

如果你的测试目标是验证DictionaryService的业务逻辑是否正确(比如是否正确调用Repo、是否处理了返回值),那应该使用真实的Service实例,只Mock它依赖的DictionaryRepo:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DictionaryServiceTest {
    @Autowired // 注入真实的Service实例
    private DictionaryService dictionaryService;

    @MockBean // Mock Service依赖的Repo
    private DictionaryRepo dictionaryRepo;

    @Test
    public void testAddDictionary() {
        // 1. 构建测试用的Dictionary对象
        Dictionary testDict = new Dictionary();
        testDict.setName("TestDict");

        // 2. 指定Mock的Repo调用save时返回带ID的对象(模拟数据库插入后的结果)
        Dictionary savedDict = new Dictionary();
        savedDict.setId(1L);
        savedDict.setName("TestDict");
        when(dictionaryRepo.save(any(Dictionary.class))).thenReturn(savedDict);

        // 3. 执行Service方法
        Dictionary actualDict = dictionaryService.addDictionary(testDict);

        // 4. 断言结果
        assertNotNull(actualDict); // 现在不会返回null了
        assertEquals(savedDict.getId(), actualDict.getId());
        assertEquals(savedDict.getName(), actualDict.getName());

        // 验证Repo的save方法是否被正确调用
        verify(dictionaryRepo, times(1)).save(testDict);
    }
}

额外检查点

  • 确认你的Dictionary类正确重写了equals()和hashCode()方法,否则assertEquals可能会失败(即使属性相同,对象引用不同也会判定不相等);
  • 检查DictionaryService的addDictionary方法逻辑,确保它会返回Repo保存后的对象(而不是返回null)——不过从你的测试报错来看,这个不是当前问题的核心,因为你用了Mock Service。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:04:22