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

Spring Boot中JUnit 5+Mockito测试ProfileController依赖注入失败求助

Spring Boot JUnit 5 测试依赖注入问题解决指南

错误根源与修复步骤

问题根源是测试类未正确初始化Mockito Mock对象,导致Spring尝试从容器中查找真实Bean。按以下步骤修复:

1. 给测试类添加Mockito扩展注解

在测试类顶部添加@ExtendWith(MockitoExtension.class),这是JUnit 5与Mockito整合的核心,负责自动初始化所有@Mock和@InjectMocks标注的对象:

@ExtendWith(MockitoExtension.class)
class ProfileControllerTest {
    @InjectMocks
    ProfileController profileController;

    @Mock
    ProfileService profileService;

    @Mock
    ProfileModelAssembler profileModelAssembler;

    @Mock
    ModelMapper modelMapper;

    // 测试方法示例
    @Test
    void testGetProfile() {
        // 定义Mock行为
        when(profileService.getById(anyLong())).thenReturn(new Profile());
        // 执行测试逻辑
        ResponseEntity<Profile> response = profileController.getProfile(1L);
        // 断言结果
        assertNotNull(response.getBody());
    }
}
  • 注意:如果测试类中同时存在@SpringBootTest或@WebMvcTest这类启动Spring容器的注解,@InjectMocks会失效,Spring会优先查找容器内的真实Bean。纯单元测试控制器逻辑无需启动容器,只保留@ExtendWith(MockitoExtension.class)即可。

2. 控制器使用无@Autowired的构造函数注入

Spring Boot 2.2+版本支持构造函数注入自动装配,无需添加@Autowired,这种方式更利于Mockito注入Mock对象:

public ProfileController(ProfileService profileService, 
                         ProfileModelAssembler profileModelAssembler, 
                         ModelMapper modelMapper) {
    this.profileService = profileService;
    this.profileModelAssembler = profileModelAssembler;
    this.modelMapper = modelMapper;
}

构造函数注入是Spring官方推荐的依赖注入方式,不仅避免了字段注入的反射依赖,也让测试时的Mock注入更稳定。

3. 区分单元测试与集成测试

  • 纯单元测试:仅测试控制器逻辑,不依赖Spring容器,用@ExtendWith(MockitoExtension.class) + @Mock + @InjectMocks组合。
  • Web集成测试:需要模拟HTTP请求、验证响应格式时,用@WebMvcTest + @MockBean替换容器中的真实Bean:
@ExtendWith(SpringExtension.class)
@WebMvcTest(ProfileController.class)
class ProfileControllerWebTest {
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    ProfileService profileService;

    @MockBean
    ProfileModelAssembler profileModelAssembler;

    @MockBean
    ModelMapper modelMapper;

    @Test
    void testProfileEndpoint() throws Exception {
        when(profileService.getById(anyLong())).thenReturn(new Profile());
        mockMvc.perform(get("/profiles/1"))
               .andExpect(status().isOk());
    }
}

入门学习资源

  1. Mockito官方用户指南:详细讲解JUnit 5整合步骤、@Mock/@InjectMocks用法及最佳实践,内容权威简洁。
  2. Spring官方测试文档:Spring Boot官网的Testing章节,明确单元测试与集成测试的边界,以及各类测试注解的适用场景。
  3. 《JUnit 5实战》:书中包含大量Mockito与JUnit 5结合的实战案例,覆盖控制器、服务层等各层测试,适合入门到进阶学习。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:10:24