PowerMockito.mockStatic() 但在调用静态方法时仍然出现 NPE
PowerMockito.mockStatic() but still getting NPE when static method is called
注意 - 我已经标记了我在问题中讨论的 3 LINE
个数字,您可能需要在代码片段中向右滚动才能看到。
我真的很难用链式 Optional.map()
s 对方法进行单元测试。
@Override
public void accept(Object message)
{
extractSenderReference(message.toString())
.map(t ->
{
t.setTransactionStatus("TAG1"); // <- LINE #1
return t;
})
.map(StaticConverter::convert) //< -LINE #2
.ifPresent(Persist::persist);
}
其中 extractSenderReference()
return 是 Obj
类型的 Optional
并且是私有方法。
我的测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassBeingTested.class, StaticConverter.class})
public class MyTest {
private ClassBeingTested updateProcessor = PowerMockito.spy(new ClassBeingTested());
private StatusDataObj statusDataObj = mock(StatusDataObj.class);
@Test
public void testSomething() throws Exception{
Obj myObj = getObj();
PowerMockito.mockStatic(StaticConverter.class);
PowerMockito.doReturn(Optional.ofNullable(myObj)).when(updateProcessor, "extractSenderReference", anyString()); // <- LINE #3
when(StaticConverter.convert(myObj)).thenReturn(statusDataObj);
updateProcessor.accept("MESSAGE1");
}
private Obj getObj(){
Obj obj = new Obj();
obj.setId(100L);
return obj;
}
}
在 LINE #1
,如我的 accept()
方法中所标记,对象 t
已处理并已成功设置其 transactionStatus
。但是在 LINE #2
时 运行 上面的测试我得到了一个 NPE。
我也尝试过 PowerMockito.spy(StaticConverter.class);
而不是 https://github.com/powermock/powermock/wiki/Mockito#mocking-static-method 的 PowerMockito.mockStatic(StaticConverter.class);
但我得到了相同的 NPE。
我的想法是 map 正在将 t
转换为 StatusDataObj
类型。所以当 map 调用 convert
时,我将存根并 return 我的类型。然而,最初我期望 LINE #3
会有效地处理 Optional
return 上 extractSenderReference()
的链式 map
调用,因为我正在使用设置了值的真实对象,但其他地方必须有空值?
您需要将 类 添加到您将在该测试中使用的 @PrepareForTest
:
@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticConverter.class, ClassBeingTested.class)
Powermock 需要注意您将在这些方面使用它 类。
尝试将方法引用 StaticConverter::convert
替换为对实际方法的显式 lambda 调用:e -> StaticConverter.convert(e)
.
我在 Powermock 模拟方法引用方面遇到了问题,但通过将其保留为显式方法调用,我可以成功地模拟这些调用。
Persist
为空。我不确定为什么 NPE 在 LINE 2
.
注意 - 我已经标记了我在问题中讨论的 3 LINE
个数字,您可能需要在代码片段中向右滚动才能看到。
我真的很难用链式 Optional.map()
s 对方法进行单元测试。
@Override
public void accept(Object message)
{
extractSenderReference(message.toString())
.map(t ->
{
t.setTransactionStatus("TAG1"); // <- LINE #1
return t;
})
.map(StaticConverter::convert) //< -LINE #2
.ifPresent(Persist::persist);
}
其中 extractSenderReference()
return 是 Obj
类型的 Optional
并且是私有方法。
我的测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassBeingTested.class, StaticConverter.class})
public class MyTest {
private ClassBeingTested updateProcessor = PowerMockito.spy(new ClassBeingTested());
private StatusDataObj statusDataObj = mock(StatusDataObj.class);
@Test
public void testSomething() throws Exception{
Obj myObj = getObj();
PowerMockito.mockStatic(StaticConverter.class);
PowerMockito.doReturn(Optional.ofNullable(myObj)).when(updateProcessor, "extractSenderReference", anyString()); // <- LINE #3
when(StaticConverter.convert(myObj)).thenReturn(statusDataObj);
updateProcessor.accept("MESSAGE1");
}
private Obj getObj(){
Obj obj = new Obj();
obj.setId(100L);
return obj;
}
}
在 LINE #1
,如我的 accept()
方法中所标记,对象 t
已处理并已成功设置其 transactionStatus
。但是在 LINE #2
时 运行 上面的测试我得到了一个 NPE。
我也尝试过 PowerMockito.spy(StaticConverter.class);
而不是 https://github.com/powermock/powermock/wiki/Mockito#mocking-static-method 的 PowerMockito.mockStatic(StaticConverter.class);
但我得到了相同的 NPE。
我的想法是 map 正在将 t
转换为 StatusDataObj
类型。所以当 map 调用 convert
时,我将存根并 return 我的类型。然而,最初我期望 LINE #3
会有效地处理 Optional
return 上 extractSenderReference()
的链式 map
调用,因为我正在使用设置了值的真实对象,但其他地方必须有空值?
您需要将 类 添加到您将在该测试中使用的 @PrepareForTest
:
@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticConverter.class, ClassBeingTested.class)
Powermock 需要注意您将在这些方面使用它 类。
尝试将方法引用 StaticConverter::convert
替换为对实际方法的显式 lambda 调用:e -> StaticConverter.convert(e)
.
我在 Powermock 模拟方法引用方面遇到了问题,但通过将其保留为显式方法调用,我可以成功地模拟这些调用。
Persist
为空。我不确定为什么 NPE 在 LINE 2
.