单元测试含WebTarget调用的方法时遇空指针,求排查
解决单元测试中WebTarget调用的空指针异常
空指针的根源是**getAuthorizationToken()方法的返回值未被正确处理**,导致你Mock的builderMock.header() stub不生效,最终调用get()时拿到的是null。
具体逻辑链:
- 你给
builderMock.header()设置的stub是when(builderMock.header(ArgumentMatchers.anyString(), ArgumentMatchers.anyString())).thenReturn(builderMock);,其中anyString()仅匹配非null的字符串 - 原方法调用
header(AUTHORIZATION, getAuthorizationToken())时,若getAuthorizationToken()执行真实逻辑返回null(或你未Mock该方法导致其返回null),第二个参数就会是null,不满足anyString()的匹配条件,Mock不会返回预设的builderMock,而是返回默认值null - 后续调用
null.get()自然抛出空指针异常
两种解决方法
方法1:Mock getAuthorizationToken()方法
如果getAuthorizationToken()是被测类ChemistryLicenseManager的public方法,直接Mock它返回非空token:
@Test public void getPathFromWS_success() throws IOException { // 保留原有的WebTarget、Builder、Response Mock代码 // 新增Mock授权token方法 when(chemistryLicenseManager.getAuthorizationToken()).thenReturn("dummy-auth-token"); String[] result = chemistryLicenseManager.getLicensePathFromWS(webTargetMock); // 断言逻辑 }
如果它是私有方法,用Mockito Spy包装真实对象来Mock私有方法:
@Before public void setUp() { // 用Spy替代直接new,以便Mock私有方法 chemistryLicenseManager = Mockito.spy(new ChemistryLicenseManager(configMock)); } @Test public void getPathFromWS_success() throws IOException { // 保留原有的WebTarget、Builder、Response Mock代码 // Mock私有方法getAuthorizationToken() doReturn("dummy-auth-token").when(chemistryLicenseManager, "getAuthorizationToken"); String[] result = chemistryLicenseManager.getLicensePathFromWS(webTargetMock); // 断言逻辑 }
方法2:修改Mock匹配器,允许null参数
若不想MockgetAuthorizationToken(),可将header()的参数匹配器改为允许null的nullable(String.class):
// 替换原有的header stub逻辑 when(builderMock.header(ArgumentMatchers.anyString(), ArgumentMatchers.nullable(String.class))).thenReturn(builderMock);
这样无论getAuthorizationToken()返回null还是非null,stub都会生效,返回builderMock,后续调用get()就不会触发空指针。
额外注意:测试代码中调用的getLicensePathFromWS与原方法名getPathFromWS是否一致?若为笔误需修正,避免出现方法找不到的问题。
内容的提问来源于stack exchange,提问作者Biraja
相关产品推荐
相关产品推荐

