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

如何在Service测试中Mock依赖?我的ScoreDAO Mock失效请求助

解决ExamServiceImpl中ScoreDAO Mock不生效返回0的问题

你遇到的核心问题是没有为Mock的scoreDAO.insert()方法指定返回值——Mockito默认会为返回int类型的方法返回0,这就是测试中返回0的原因。下面是两种测试方式的正确实现,同时规避常见的坑:


方式一:使用@SpringBootTest + @MockBean

这种方式适合需要加载Spring容器的集成测试,用@MockBean替换容器中的真实依赖:

@SpringBootTest
class ExamServiceImplSpringBootTest {

    @MockBean
    private ScoreDAO scoreDAO;

    @MockBean
    private SubjectService subjectService;

    @Autowired
    private ExamServiceImpl examService;

    @Test
    void insertScore_ShouldReturn1_WhenInsertSuccess() {
        // 准备测试数据
        Score testScore = new Score();
        testScore.setStudentId(1001L);
        testScore.setSubjectId(2L);
        testScore.setScore(90);

        // 关键:指定Mock的insert方法返回1(模拟插入成功)
        when(scoreDAO.insert(any(Score.class))).thenReturn(1);

        // 按需Mock SubjectService的依赖方法
        when(subjectService.validateSubject(2L)).thenReturn(true);

        // 执行测试方法
        int result = examService.insertScore(testScore);

        // 断言结果
        assertEquals(1, result);
        // 验证scoreDAO的insert方法是否被正确调用
        verify(scoreDAO, times(1)).insert(any(Score.class));
    }
}

方式二:使用MockitoJUnitRunner + @Mock + @InjectMocks

这种方式是纯单元测试,不需要加载Spring容器,直接通过Mockito注入依赖:

@RunWith(MockitoJUnitRunner.class)
class ExamServiceImplMockitoTest {

    @Mock
    private ScoreDAO scoreDAO;

    @Mock
    private SubjectService subjectService;

    // 将@Mock标注的依赖注入到ExamServiceImpl实例中
    @InjectMocks
    private ExamServiceImpl examService;

    @Test
    void insertScore_ShouldReturnExpectedValue() {
        Score testScore = new Score();
        testScore.setStudentId(1002L);
        testScore.setSubjectId(3L);
        testScore.setScore(80);

        // 指定Mock返回值,这里用eq()做精确匹配,也可以用any()模糊匹配
        when(scoreDAO.insert(eq(testScore))).thenReturn(1);
        when(subjectService.validateSubject(3L)).thenReturn(true);

        int result = examService.insertScore(testScore);

        assertEquals(1, result);
        // 验证依赖方法的调用次数和参数
        verify(scoreDAO, only()).insert(testScore);
        verify(subjectService, times(1)).validateSubject(3L);
    }
}

常见问题排查

  1. 忘记指定Mock返回值:这是最常见的原因,Mockito对int/long等基本类型的方法默认返回0,必须显式用when(...).thenReturn()指定期望的返回值。
  2. @InjectMocks注入失败:如果ExamServiceImpl使用构造方法注入依赖,确保构造方法的参数类型与@Mock的对象完全匹配;如果是字段注入,确保字段不是private(或开启Mockito的访问权限)。
  3. @SpringBootTest中依赖未完全Mock:如果ExamServiceImpl还有其他未用@MockBean替换的依赖,可能导致容器启动失败或使用真实实例,需要把所有依赖都替换为Mock。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:30:49