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

含Post方法的Controller单元测试报NullPointerException排查

空指针问题根因与修复方案

你的空指针异常完全由测试类中Mockito注解的错误使用导致,控制器中this.reporterService实际为null,调用方法时自然触发NPE,具体问题和修复方式如下:

核心错误点

  • 注解使用逻辑颠倒:@InjectMocks仅用于标记待测试的目标对象(即需要被注入依赖的类),你错误地将该注解加在了依赖类ReporterService上,导致Mockito不会将reporterService作为依赖注入到控制器中。
  • 手动实例化被测试类:你手动通过new ReportEmailController()创建了控制器实例,该实例脱离Mockito容器管理,所有依赖都不会被自动注入。
  • 测试变量未赋值:测试方法中调用getIdEmailInfoRequest()后没有将返回值赋值给idEmailInfoRequest变量,该变量本身为null,即使修复依赖注入问题也会触发后续异常。
  • 测试层级混乱:Controller层单元测试不需要穿透调用Repository层逻辑,直接mock Service层的返回值即可,你现在的mock逻辑写在Repository层,就算依赖注入正常也无法被Service调用到。

修复后的测试类代码

@RunWith(MockitoJUnitRunner.class)            
public class ReportEmailControllerTest  {
            
    // 所有被依赖的下游组件统一用@Mock标记
    @Mock
    private ReporterService reporterService;
            
    @Mock
    private EmailInfoRepository emailInfoRepository;
            
    // 待测试的Controller用@InjectMocks标记,不要手动new实例
    @InjectMocks
    private ReportEmailController reportEmailController;

    private IdEmailInfoRequest idEmailInfoRequest;

    @Before
    public void initTestData() {
        idEmailInfoRequest = getIdEmailInfoRequest();
    }
            
    @Test
    public void testIdEmailInfo_whenRequestIsValidReturnValidList() {
        // 构造mock返回结果
        List<EmailInfoIdParams> mockServiceResult = new ArrayList<>();
        EmailInfoIdParams testParam = new EmailInfoIdParams();
        mockServiceResult.add(testParam);

        // mock Service层方法返回,匹配任意IdEmailInfoRequest类型入参
        when(reporterService.getIdEmailInfo(any(IdEmailInfoRequest.class))).thenReturn(mockServiceResult);
        
        // 调用目标接口方法
        ResponseEntity<EmailInfoIdResponse> response = reportEmailController.idEmailInfo("1","user",idEmailInfoRequest);
        
        // 结果断言
        assertEquals(HttpStatus.ACCEPTED, response.getStatusCode());
        assertNotNull(response.getBody());
        assertEquals("SUCCESS", response.getBody().getStatus());
        assertNotEquals(0, response.getBody().getEmailInfoIdParams().size());
    }
}

补充说明:如果需要单独测试ReporterService的逻辑,单独编写Service层测试类即可:给ReporterService加@InjectMocks注解,给它依赖的EmailInfoRepository加@Mock注解,不要把不同层级的测试逻辑混在同一个测试类里。

内容的提问来源于stack exchange,提问作者Defne Sabancı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:21:40