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

Mockito测试报错‘期望调用但未执行:无交互’问题排查

问题分析与解决方案

错误原因

  1. 重复初始化导致Mock配置失效:
    测试类已添加@ExtendWith(MockitoExtension.class),该注解会自动初始化所有@Mock和@Spy标注的对象。但setUp方法中又调用了MockitoAnnotations.openMocks(this),会重新初始化Mock对象,覆盖之前配置的when(entityRepository.findByRefNumber(...))逻辑,导致Repository的Mock行为失效,服务方法查询不到实体,触发“未找到实体”日志,最终Verify断言失败。

  2. @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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:25:10