SpringBoot API测试时Controller层出现NullPointerException问题求助
问题根因
你遇到的空指针是三个常见的测试配置错误共同导致的:
- JUnit版本注解不匹配:你使用了JUnit5的
@ExtendWith(SpringExtension.class)扩展,但用了JUnit4的@Before注解,JUnit5不会识别该注解,导致setup()初始化方法从未执行,mockMvc对象未初始化,调用perform()时直接抛出空指针。 - Mock对象未标记
@Mock注解:@InjectMocks只会自动注入被@Mock/@Spy注解修饰的依赖,你手动创建的companiaServicemock对象不会被注入到ControllerAPI实例中,导致Controller里的companiaService为空,接口调用时也会触发空指针。 - 潜在的静态导入缺失:如果没有静态导入
MockMvcRequestBuilders.get,代码中的get()方法会识别失败,参数为空也会触发空指针。
修复方案
1. 修正测试类注解
首先替换错误的生命周期注解,给mock对象加上@Mock注解:
import org.junit.jupiter.api.BeforeEach; import org.mockito.Mock; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @ExtendWith(SpringExtension.class) @ContextConfiguration class ControllerAPITest { String token = "xxx"; @InjectMocks private ControllerAPI controllerAPI; // 加@Mock注解,让@InjectMocks可以自动注入 @Mock private CompaniaServiceImpl companiaService; private MockMvc mockMvc; // JUnit5用@BeforeEach代替JUnit4的@Before @BeforeEach public void setup() throws Exception{ MockitoAnnotations.openMocks(this); // initMocks已废弃,推荐用openMocks this.mockMvc = MockMvcBuilders.standaloneSetup(controllerAPI).build(); } @Test void getByField() throws Exception { Map<String, List<Object>> response = Collections.singletonMap("success", List.of("nombre1")); Mockito.when(companiaService.getCompaniaByfield(1L,"name")).thenReturn(response); this.mockMvc.perform( get("/companias/{companiaId}/{field_name}", 1L, "name") .header("authorization", "Bearer " + token) .contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()) .andExpect(jsonPath("$.success[0]").isNotEmpty()) .andExpect(jsonPath("$.success[0]").value("nombre1")); } }
2. 可选优化Controller代码
Controller已经使用构造函数注入,不需要再加字段上的@Autowired注解,去掉即可避免冗余:
@RestController @RequestMapping(path = "/companias") public class ControllerAPI { private final CompaniaServiceImpl companiaService; // Spring 4.3+版本支持构造函数注入省略@Autowired public ControllerAPI(CompaniaServiceImpl companiaService) { this.companiaService = companiaService; } // 其余方法保持不变 }
内容的提问来源于stack exchange,提问作者Varox
相关产品推荐
相关产品推荐

