Mockito Mock EntityManager不生效,单元测试仍调用数据库该如何解决?
Mock失效原因分析
- EntityManager未正确Mock注入
你当前的测试逻辑里仅Mock了Query对象,但如果Service依赖的EntityManager实例不是你测试中绑定了Stub规则的Mock对象(比如使用@SpringBootTest加载完整Spring上下文时,EntityManager是容器生成的真实实例,而非Mock对象),所有对em的调用都会走真实逻辑,Mock规则自然不会触发。 - 方法返回类型不匹配
你Service中调用em.createQuery()返回的是Query类型,但测试中Mock的是TypedQuery类,Mockito的Stub规则对方法参数、返回值的匹配是严格的,类型不匹配会导致Stub规则失效,最终调用真实的createQuery方法。 - JPQL字符串匹配误差
你测试代码中写死的JPQL字符串如果和Service中实际的字符串存在空格、换行、大小写等细微差异,Mockito的参数默认精确匹配规则会判定为不匹配,不会返回你Mock的Query对象。 - Mock方法Stub不完整
Service中调用了Query的setParameter和getResultList两个方法,你仅Stub了getResultList,未Stub的setParameter在部分Mockito版本中会返回null或触发默认行为,导致后续逻辑中断走真实调用。
单元测试避免触发真实数据库调用的方案
- 分层测试做隔离
不要在Controller层单元测试中校验DAO层逻辑:Controller层测试用@WebMvcTest注解仅加载目标Controller相关Bean,用@MockBean直接Mock Service层的getPrice方法,从上层截断到DAO的调用链路,不需要Mock底层EntityManager,稳定性更高。
示例Stub写法:@MockBean private ReservationService reservationService; @Test void getPaymentById() throws Exception { List<Reservation> mockList = new LinkedList<>(); // 直接Stub Service层方法返回 Mockito.when(reservationService.getPrice(1L)) .thenReturn(new DefaultResponseDTO(200, ResponseStatus.OK, "Price Calculated.", mockList)); // 后续mockMvc调用逻辑不变 } - Service层单测用Mockito独立运行
测试Service层逻辑时不要加载Spring上下文,用@ExtendWith(MockitoExtension.class)注解,用@Mock注入EntityManager,@InjectMocks注入目标Service实例,保证所有依赖都是Mock对象:@ExtendWith(MockitoExtension.class) public class ReservationServiceTest { @Mock private EntityManager em; @InjectMocks private ReservationService reservationService; @Test void testGetPrice() { Query mockQuery = Mockito.mock(Query.class); List<Reservation> mockList = new LinkedList<>(); // 用宽松参数匹配器避免字符串匹配问题 Mockito.when(em.createQuery(anyString())).thenReturn(mockQuery); // 完整Stub所有调用的方法 Mockito.when(mockQuery.setParameter(anyString(), any())).thenReturn(mockQuery); Mockito.when(mockQuery.getResultList()).thenReturn(mockList); Object result = reservationService.getPrice(1L); // 断言结果即可 } } - DAO层测试用内存数据库替代真实库
如果需要测试持久化逻辑,单独给DAO层写测试,用H2等内存数据库,配置专门的测试数据源,不会操作真实业务数据库。
内容的提问来源于stack exchange,提问作者Prasad Darshana
相关产品推荐
相关产品推荐

