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

Mockito模拟HttpHeaders移除setUp()触发空指针异常求解

解决Mockito模拟HttpHeaders时移除setUp()导致的NullPointerException问题

嘿,我明白你的困扰——刚接触Mockito,本来想简单模拟个HttpHeaders,结果移除setUp()就报NPE,还要写一堆繁琐的子类实现,确实头疼。让我帮你搞定这个问题!

问题根源分析

首先得搞清楚为什么移除setUp()会报错:你用了@Mock注解标注HttpHeaders headers,Mockito会给你生成一个mock对象,但这个mock对象的所有方法默认返回null。之前你的setUp()里手动new了一个HttpHeaders的子类,手动实现了getRequestHeaders()等方法返回非null的对象(比如MultivaluedHashMap),所以调用headers.getRequestHeaders().putSingle()不会出问题;但移除setUp后,mock的getRequestHeaders()返回null,再调用putSingle自然就触发NullPointerException了。


方案一:简洁版setUp配置(适合多测试方法复用)

不用再写一堆子类覆盖方法,只用几行代码配置mock的行为就行。如果多个测试方法都需要用到这个HttpHeaders的配置,用@Before做统一初始化最方便:

@RunWith(SpringJUnit4ClassRunner.class)
public class ValidateAndQuotetValidatorTest {
    @InjectMocks
    private ValidateAndQuotetValidator validator;
    @Mock
    private HttpHeaders headers;

    @Before
    public void setUp() throws Exception {
        // 初始化Mockito(确保@Mock注解生效)
        MockitoAnnotations.initMocks(this);
        
        // 配置getRequestHeaders返回一个空的MultivaluedHashMap,避免null
        MultivaluedMap<String, String> mockRequestHeaders = new MultivaluedHashMap<>();
        Mockito.when(headers.getRequestHeaders()).thenReturn(mockRequestHeaders);
        
        // 如果你的测试还用到其他方法,比如getRequestHeader,也可以按需配置
        Mockito.when(headers.getRequestHeader(Mockito.anyString())).thenReturn(new ArrayList<>());
    }

    @Test(expected = ServiceException.class)
    public void test_validateRequest_12() throws Exception {
        headers.getRequestHeaders().putSingle(ExternalPartnerUtil.PARTNER_NAME, "");
        headers.getRequestHeaders().putSingle(ExternalPartnerUtil.AGENT_ID, "asd");
        validator.validateHeaders(headers);
    }
}

这样setUp的代码非常简洁,完全替代了之前繁琐的子类实现。

方案二:无setUp,直接在测试方法内配置

如果只有这一个测试方法需要用到这个HttpHeaders,也可以去掉@Before,直接在测试方法里配置mock行为:

@RunWith(SpringJUnit4ClassRunner.class)
public class ValidateAndQuotetValidatorTest {
    @InjectMocks
    private ValidateAndQuotetValidator validator;
    @Mock
    private HttpHeaders headers;

    @Test(expected = ServiceException.class)
    public void test_validateRequest_12() throws Exception {
        // 初始化Mockito(如果SpringJUnit4ClassRunner没自动处理的话)
        MockitoAnnotations.initMocks(this);
        
        // 配置getRequestHeaders返回非null的Map
        MultivaluedMap<String, String> mockRequestHeaders = new MultivaluedHashMap<>();
        Mockito.when(headers.getRequestHeaders()).thenReturn(mockRequestHeaders);
        
        // 直接操作这个Map,不用通过headers.getRequestHeaders()链式调用(更安全)
        mockRequestHeaders.putSingle(ExternalPartnerUtil.PARTNER_NAME, "");
        mockRequestHeaders.putSingle(ExternalPartnerUtil.AGENT_ID, "asd");
        
        validator.validateHeaders(headers);
    }
}

这里直接操作我们创建的mockRequestHeaders,比链式调用更不容易出错,也更清晰。

额外小提示

如果你不需要Spring的上下文支持,还可以把@RunWith(SpringJUnit4ClassRunner.class)换成@RunWith(MockitoJUnitRunner.class),这样Mockito会自动初始化@Mock的对象,连MockitoAnnotations.initMocks(this)都可以省去。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:27:43