移除@SpringBootTest后MockMvc空指针问题求助(JUnit+SpringBoot)
问题原因与解决方案
核心原因
@ExtendWith(MockitoExtension.class) 仅负责处理Mockito的Mock对象注入逻辑,不会初始化Spring MVC相关的组件(比如MockMvc)。而@SpringBootTest会加载完整的Spring上下文,自动帮你配置并注入MockMvc,所以移除后mockMvc就会因为没人初始化而报空指针。
两种可行解决方案
方案1:用轻量Spring MVC测试注解(推荐)
使用@WebMvcTest替代@SpringBootTest,它只会加载Spring MVC相关的最小上下文,既保证测试正确性,又大幅提升加载速度,同时结合@MockBean注入Controller依赖的服务类:
@WebMvcTest(YourTargetController.class) @ExtendWith(MockitoExtension.class) public class ControllerTest { @Autowired private MockMvc mockMvc; // 用@MockBean注入Controller依赖的Service,替代@Mock+@InjectMocks @MockBean private YourService yourService; @Test void testControllerEndpoint() throws Exception { // 模拟Service返回值 when(yourService.getSomeData()).thenReturn("mockResponse"); // 执行请求并断言 mockMvc.perform(get("/api/your-endpoint")) .andExpect(status().isOk()) .andExpect(content().string("mockResponse")); } }
方案2:手动构建MockMvc(完全脱离Spring上下文)
如果不需要Spring MVC的上下文支持,只想单纯测试Controller逻辑,可以手动通过MockMvcBuilders构建MockMvc:
@ExtendWith(MockitoExtension.class) public class ControllerTest { private MockMvc mockMvc; @InjectMocks private YourTargetController yourController; @Mock private YourService yourService; @BeforeEach void setUp() { // 手动初始化MockMvc mockMvc = MockMvcBuilders.standaloneSetup(yourController).build(); } @Test void testControllerLogic() throws Exception { when(yourService.getSomeData()).thenReturn("mockResult"); mockMvc.perform(post("/api/submit") .contentType(MediaType.APPLICATION_JSON) .content("{\"param\":\"test\"}")) .andExpect(status().isOk()); } }
方案选择建议
- 若需要测试完整的Spring MVC流程(比如拦截器、消息转换器、参数校验等),选方案1;
- 若仅测试Controller的业务逻辑,不需要Spring上下文参与,选方案2,速度最快。
内容的提问来源于stack exchange,提问作者SeNTiHaDeS
相关产品推荐
相关产品推荐

