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

Spring Boot中@MockBean无法修改返回值问题排查

Spring Boot测试中@MockBean模拟未生效的问题排查与解决

问题根源

你的控制器代码直接通过new创建了TestServiceImpl实例,完全绕过了Spring的依赖注入容器:

public TestService testService = new TestServiceImpl(); // 直接实例化,不依赖Spring容器

@MockBean的作用是替换Spring容器中对应的Bean实例,但你的控制器根本没有从Spring容器获取TestService实例,而是用自己创建的对象,所以模拟操作完全不会影响到控制器的逻辑,自然返回原始的"Hello"。

解决方案

1. 修改控制器,使用Spring依赖注入

把控制器中直接new实例的代码改成依赖注入方式,推荐使用构造注入(Spring官方推荐,避免空指针问题,也更利于测试):

@RestController
public class ExampleController {
    private final TestService testService;

    // 构造注入
    public ExampleController(TestService testService) {
        this.testService = testService;
    }

    @GetMapping("/test")
    public String test() {
        return testService.greet();
    }
}

如果习惯用@Autowired,也可以这样写:

@RestController
public class ExampleController {
    @Autowired
    private TestService testService;

    @GetMapping("/test")
    public String test() {
        return testService.greet();
    }
}

2. 调整测试类(可选,推荐Mock接口)

测试类中可以把@MockBean的类型改成接口TestService,更符合面向接口编程的思想,也更灵活:

@RunWith(SpringRunner.class)
@WebMvcTest(ExampleController.class) // 建议指定具体控制器类,而非Application类
class ExampleApplicationTests {
    @Autowired
    MockMvc mockMvc;

    @MockBean
    private TestService testService; // Mock接口而非实现类

    @Test
    void test() throws Exception{
        doReturn("Hi").when(testService).greet();

        mockMvc.perform(MockMvcRequestBuilders
                .get("/test")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", notNullValue()))
                .andExpect(jsonPath("$", is("Hi")));
    }
}

验证效果

修改后,控制器会从Spring容器获取TestService实例,而@MockBean已经替换了容器中的实例,此时测试会调用模拟的greet方法返回"Hi",测试即可通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:52:54