为什么我在尝试模拟 WebClient 调用时会在 bodyValue 上收到 NPE?

Why am I getting a NPE on bodyValue when trying to mock a WebClient call?

我正在尝试测试以下代码...

WebClient client = WebClient.create(request.getEndpointUrl());
Mono<MessageResponseItem[]> response = client.post()
                                             .uri("...")
                                             .bodyValue(request) // NPE happens here
                                             .retrieve()
                                             .bodyToMono(MessageResponseItem[].class);

我试着做这样的单元测试...

@PrepareForTest(WebClient.class)
@RunWith(PowerMockRunner.class)
public class MyServiceTest {
    @Mock
    private WebClient webClientMock;
    @Mock
    private WebClient.RequestHeadersSpec requestHeadersMock;
    @Mock
    private WebClient.RequestHeadersUriSpec requestHeadersUriMock;
    @Mock
    private WebClient.RequestBodyUriSpec requestBodyUriMock;
    @Mock
    private WebClient.ResponseSpec responseMock;

    private MyService service = new MyService();

    @Before
    public void setup(){
        PowerMockito.mockStatic(WebClient.class);
        BDDMockito.given(WebClient.create(any())).willReturn(webClientMock);
    }
    @Test
    public void HappyPath(){
        MessageResponseItem item = new MessageResponseItem();
        item.setRecipientId("id");
        item.setResponseText("response");
        MessageResponseItem[] items = {item};
        MyRequest request = new MyRequest();
        request.setSomething("something");
        ....
        when(webClientMock.post()).thenReturn(requestBodyUriMock);
        when(requestHeadersUriMock.uri("...")).thenReturn(requestHeadersMock);
        when(requestBodyUriMock.bodyValue(any(MyRequest.class))).thenReturn(requestHeadersMock);
        when(requestHeadersMock.retrieve()).thenReturn(responseMock);
        when(responseMock.bodyToMono(MessageResponseItem[].class)).thenReturn(Mono.just(items));
        MessageResponseItem[] result = service.callSomething(request).block();
        assertThat(result.length).isEqualTo(1);
        assertThat(result[0].getResponseText()).isEqualTo("response");
    }
}

那么,为什么我没有 NPE 就无法通过 bodyValue?我搞砸了嘲笑吗?

我试着改成...

@Mock
private WebClient.RequestHeadersUriSpec requestHeadersUriMock;
@Mock
private WebClient.RequestBodySpec requestBodyMock;
...
when(webClientMock.post()).thenReturn(requestBodyUriMock);
when(requestBodyUriMock.uri("...")).thenReturn(requestBodyMock);
when(requestBodyUriMock.bodyValue(any(MyeRequest.class))).thenReturn(requestHeadersMock);
when(requestHeadersMock.retrieve()).thenReturn(responseMock);
when(responseMock.bodyToMono(MessageResponseItem[].class)).thenReturn(Mono.just(items));

同样的问题

配对后:

when(webClientMock.post()).thenReturn(requestBodyUriMock);
when(requestBodyUriMock.uri(any(String.class))).thenReturn(requestBodyMock);
when(requestBodyMock.bodyValue(any())).thenReturn(requestHeadersMock);
when(requestHeadersMock.retrieve()).thenReturn(responseMock);
when(responseMock.bodyToMono(MessageResponseItem[].class)).thenReturn(Mono.just(items));