如何在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); } }
常见问题排查
- 忘记指定Mock返回值:这是最常见的原因,Mockito对int/long等基本类型的方法默认返回0,必须显式用
when(...).thenReturn()指定期望的返回值。 - @InjectMocks注入失败:如果ExamServiceImpl使用构造方法注入依赖,确保构造方法的参数类型与
@Mock的对象完全匹配;如果是字段注入,确保字段不是private(或开启Mockito的访问权限)。 - @SpringBootTest中依赖未完全Mock:如果ExamServiceImpl还有其他未用
@MockBean替换的依赖,可能导致容器启动失败或使用真实实例,需要把所有依赖都替换为Mock。
内容的提问来源于stack exchange,提问作者Jupiter
相关产品推荐
相关产品推荐

