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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:24:04