Mockito测试报错‘期望调用但未执行:无交互’问题排查
问题分析与解决方案
错误原因
重复初始化导致Mock配置失效:
测试类已添加@ExtendWith(MockitoExtension.class),该注解会自动初始化所有@Mock和@Spy标注的对象。但setUp方法中又调用了MockitoAnnotations.openMocks(this),会重新初始化Mock对象,覆盖之前配置的when(entityRepository.findByRefNumber(...))逻辑,导致Repository的Mock行为失效,服务方法查询不到实体,触发“未找到实体”日志,最终Verify断言失败。@Spy与@InjectMocks组合的注入冲突:
对EntityManagementService同时使用@Spy和@InjectMocks时,Mockito的依赖注入逻辑无法正确将Mock的entityRepository注入到Spy对象中。@Spy创建的是真实服务对象的代理,而@Autowired修饰的entityRepository字段在测试环境未被Spring容器初始化,@InjectMocks无法完成替换,导致服务方法调用的是未初始化的Repository(或null),而非Mock对象,因此Verify检测不到交互。
修复后的测试代码
方案一:保留@Spy,手动注入Mock依赖
@ExtendWith(MockitoExtension.class) public class EntityManagementServiceTest { @Mock private EntityRepository entityRepository; @Spy private EntityManagementService entityManagementService; @BeforeEach void setUp() { // 手动将Mock的Repository注入到Spy对象中 ReflectionTestUtils.setField(entityManagementService, "entityRepository", entityRepository); Entity mockEntity = new Entity(); mockEntity.setRefNumber("referenceNumber"); when(entityRepository.findByRefNumber("referenceNumber")).thenReturn(Optional.of(mockEntity)); } @Test void shouldInvokeRepositoryWhenProcessingEntityUpdate() { entityManagementService.processEntityUpdate("referenceNumber"); verify(entityRepository).findByRefNumber("referenceNumber"); // 如需验证updateEntityDetails调用,可添加: // verify(entityManagementService).updateEntityDetails(any(Entity.class)); } }
方案二:去掉@Spy,仅用@InjectMocks(无需Spy场景)
如果不需要对服务类方法做Spy(比如无需验证updateEntityDetails调用),直接用@InjectMocks创建服务实例即可:
@ExtendWith(MockitoExtension.class) public class EntityManagementServiceTest { @Mock private EntityRepository entityRepository; @InjectMocks private EntityManagementService entityManagementService; @BeforeEach void setUp() { Entity mockEntity = new Entity(); mockEntity.setRefNumber("referenceNumber"); when(entityRepository.findByRefNumber("referenceNumber")).thenReturn(Optional.of(mockEntity)); } @Test void shouldInvokeRepositoryWhenProcessingEntityUpdate() { entityManagementService.processEntityUpdate("referenceNumber"); verify(entityRepository).findByRefNumber("referenceNumber"); } }
关键注意事项
- 避免重复初始化:
@ExtendWith(MockitoExtension.class)和MockitoAnnotations.openMocks(this)二选一即可,不要同时使用。 - 使用
@Spy时,优先手动处理依赖注入(如ReflectionTestUtils),避免@InjectMocks的注入逻辑冲突。
内容的提问来源于stack exchange,提问作者Japkutija
相关产品推荐
相关产品推荐

