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

Spring Controller Mockito测试出现NullPointerException问题求助

Spring Controller测试:搞定MockMvc空指针与TeacherService注入问题

先解决MockMvc空指针

你的测试类里MockMvc mvc字段没加@Autowired注解,@AutoConfigureMockMvc会自动创建MockMvc实例,但得让Spring把它注入到测试类里才行。直接给mvc加上@Autowired就行。另外你同时加了@ExtendWith(MockitoExtension.class)和@ExtendWith(SpringExtension.class),其实SpringExtension已经包含了Mockito的支持,删掉MockitoExtension的注解即可,或者换成@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)配合@AutoConfigureMockMvc,配置更简洁。

TeacherService的注入是对的

@MockBean用法没问题,它会在Spring测试上下文里把真实的TeacherService替换成Mock对象,Controller能正常注入这个Mock,不用调整。

测试类里还有几个坑要踩平

  1. 删掉@InjectMocks private TeacherForm teacherForm;:TeacherForm是表单DTO,不需要依赖注入,这个注解会让teacherForm变成null,后面调用getId()直接触发空指针。表单数据是通过请求参数传递的,测试里已经用.param()传值,无需提前实例化。
  2. 修正Mock的返回值:你的Controller里teacherService.findById()返回的是Optional<Teacher>,之前返回null会导致调用isPresent()时抛出异常,应该改成返回Optional.empty(),用anyLong()匹配任意ID更灵活:
    when(teacherService.findById(anyLong())).thenReturn(Optional.empty());
    
  3. 想更轻量的话,用@WebMvcTest(TeacherController.class)替代@ExtendWith和@AutoConfigureMockMvc,这个注解只会加载Controller相关的Bean,测试启动更快。

修正后的完整测试代码

@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
public class TeacherControllerMockTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private TeacherService teacherService;

    @Captor
    private ArgumentCaptor<Teacher> teacherCaptor;

    @Test
    void addTeacherPostNonExistingTeacher() throws Exception {
        // Mock教师不存在的场景
        when(teacherService.findById(anyLong())).thenReturn(Optional.empty());

        mvc.perform(post("/addTeacher")
                        .param("firstName", "Anne-Marie")
                        .param("lastName", "Kermarrec")
                )
                .andExpect(status().is3xxRedirection())
                .andReturn();

        verify(teacherService, atLeastOnce()).saveTeacher(teacherCaptor.capture());
        Teacher capturedTeacher = teacherCaptor.getValue();
        assertEquals("Kermarrec", capturedTeacher.getLastName());
    }
}

可选轻量配置(用@WebMvcTest)

@WebMvcTest(TeacherController.class)
public class TeacherControllerMockTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private TeacherService teacherService;

    @Captor
    private ArgumentCaptor<Teacher> teacherCaptor;

    // 测试方法和上面一致
}

最后提醒:你的Controller里的TeacherService得是Spring管理的(比如用@Autowired或构造注入),不然Mock对象没法正常注入进去。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 17:45:32