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-methodPowerMockito.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.