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

使用@MockBean编写测试用例时出现java.lang.IllegalStateException重复Mock定义

解决Spring Boot测试中Duplicate mock definition异常问题

我之前也碰到过一模一样的问题,你这个异常的核心原因是同时使用了两种Mock初始化方式,导致Spring上下文里重复创建了ThirdPartyService的Mock实例。下面给你一步步拆解解决方案:

问题根源分析

你在测试类里同时做了两件冲突的事:

  • 使用Spring Boot的@MockBean注解标记ThirdPartyService,这个注解会让Spring自动在测试上下文里创建并管理该类的Mock实例;
  • 在@Before方法里调用MockitoAnnotations.initMocks(this),这是Mockito原生的初始化Mock的方式,它会再次创建一个ThirdPartyService的Mock实例。

两种方式叠加,就会触发Spring的重复Mock定义检查,抛出你看到的IllegalStateException。

解决方案步骤

1. 移除Mockito原生的初始化代码

直接删掉测试类里的initMocks方法,因为@MockBean已经足够完成Mock的初始化和管理:

// 删掉这个冗余的初始化方法
// @Before
// public void initMocks(){
//     MockitoAnnotations.initMocks(this);
// }

2. 修正测试方法里的Mock引用笔误

你的测试代码里用了ts.decrypt,但你的Mock字段是thirdPartyService,这是明显的笔误,会导致找不到Mock对象,修正后应该是:

@Test
public void test() throws Exception {
    // 修正为正确的Mock字段引用
    when(thirdPartyService.decrypt("encryptedText")).thenReturn("decryptedText");
    Request req = Request.builder().name("name123").build(); 
    ResultActions action = performPost("/test", req); 
    action.andExpect(status().isOk()); 
}

3. 检查父类和上下文是否有重复Mock

虽然你提供的IntegrationTest父类代码里没有相关配置,但也要确保:

  • 父类或者其他被扫描的配置类里没有再次定义ThirdPartyService的@MockBean或@Mock;
  • @ComponentScan("com")没有扫描到其他会创建ThirdPartyService实例的配置(不过@MockBean会自动替换掉原有的@Service实例,这一点一般不会有问题)。

修正后的完整测试类代码

@ComponentScan("com") 
@PropertySource({"classpath:/api.properties", "classpath:/common.properties"}) 
@SpringBootConfiguration 
@RunWith(SpringRunner.class) 
@SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) 
@Transactional 
public class TestControllerTest extends IntegrationTest { 
    @MockBean 
    ThirdPartyService thirdPartyService; 

    @Test 
    public void test() throws Exception { 
        when(thirdPartyService.decrypt("encryptedText")).thenReturn("decryptedText");
        Request req = Request.builder().name("name123").build(); 
        ResultActions action = performPost("/test", req); 
        action.andExpect(status().isOk()); 
    } 
}

这样修改后,Spring只会创建一个ThirdPartyService的Mock实例,重复定义的异常就会消失,同时你的Mock逻辑也能正常生效,调用decrypt方法时会返回你预设的"decryptedText"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:28:25