有请求正文时模拟WebClient帖子

时间:2019-11-17 14:18:02

标签: java spring unit-testing mockito webclient

关于模拟WebClient对象,存在几个有用的答案的问题。但是当我用身体做文章时仍然有问题。我只是使用 Mockito ,而不是 mockwebserver

这是我正在测试的方法:

public class RestClient extends BaseRestClient {
 ...
 public <T,G> Mono<T> post(String url, G req, Class<T> resp) throws IOException {
        Mono<T> response = null;

        response = this.getWebClient().post()
                    .uri(url)
                    .header(HttpHeaders.CONTENT_TYPE,JSON_CONTENT_TYPE)
                    .accept(MediaType.APPLICATION_JSON)
                    //.body(BodyInserters.fromObject(req))
                    .header(HttpHeaders.AUTHORIZATION, BEARER + token)
                    .retrieve()
                    .bodyToMono(resp).log();

        return response.map(resp::cast);
    }
 ...

注意注释掉的正文行。

这是与上面的代码配合使用的测试-再次注意测试中注释掉的行:

@Mock
WebClient webClient;

@Mock
WebClient.RequestBodyUriSpec requestBodyUriSpec;

@Mock
WebClient.RequestHeadersSpec requestHeadersSpec;

@Mock
WebClient.RequestBodySpec requestBodySpec;

@Mock
WebClient.ResponseSpec responseSpec;

@InjectMocks
RestClient restClient;

@Test
    public void postTest() throws IOException {
        when(webClient.post()).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.uri(anyString())).thenReturn(requestBodySpec);
        when(requestBodySpec.header(any(),any())).thenReturn(requestBodySpec);
        when(requestBodySpec.accept(any())).thenReturn(requestBodySpec);
        when(responseSpec.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
                .thenReturn(Mono.just("resp"));

        //when(requestBodySpec.body(any())).thenReturn(requestHeadersSpec);
        when(requestBodySpec.retrieve()).thenReturn(responseSpec);

        restClient.post("http://sampleurl",Object.class, Object.class);
    }

同样,一切正常。但是,如果我将注释掉的行放回代码中,这意味着该帖子有一个正文,然后通过将注释掉的行放回测试中来模拟正文,那么我将得到 NullPointerException 代码中的 .retrieve()。就像我缺少要模拟的对象一样。

我甚至嘲笑.retrieve()来 requestHeadersSpec requestBodyUriSpec

when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
when(requestBodyUriSpec.retrieve()).thenReturn(responseSpec);

仍然没有成功。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

如果您使用的是new RestClient(),则无需创建@InjectMocks。 另外,由于您在嘲笑WebClient,所以不需要嘲笑WebClient. *`。

代码变成

@Mock
WebClient webClient;

@InjectMocks
RestClient restClient;

@Test
    public void postTest() throws IOException {
        when(webClient.post()).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.uri(anyString())).thenReturn(requestBodySpec);
        when(requestBodySpec.header(any(),any())).thenReturn(requestBodySpec);
        when(requestBodySpec.accept(any())).thenReturn(requestBodySpec);
        when(responseSpec.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
                .thenReturn(Mono.just("resp"));

        //when(requestBodySpec.body(any())).thenReturn(requestHeadersSpec);
        when(requestBodySpec.retrieve()).thenReturn(responseSpec);

        restClient.post("http://sampleurl",Object.class, Object.class);
    }

答案 1 :(得分:0)

我错过了模拟requestHeadersSpec的“ header”方法:

when(requestHeadersSpec.header(any(),any())).thenReturn(requestHeadersSpec);

所以,现在可以正常工作了:

@Test
    public void postTest() throws IOException {
        when(webClient.post()).thenReturn(requestBodyUriSpec);
        when(requestBodyUriSpec.uri(anyString())).thenReturn(requestBodySpec);
        when(requestBodySpec.header(any(),any())).thenReturn(requestBodySpec);

        when(requestHeadersSpec.header(any(),any())).thenReturn(requestHeadersSpec);

        when(requestBodySpec.accept(any())).thenReturn(requestBodySpec);
        when(requestBodySpec.body(any())).thenReturn(requestHeadersSpec);
        when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
        when(responseSpec.bodyToMono(ArgumentMatchers.<Class<String>>notNull()))
                .thenReturn(Mono.just("resp"));

        Assert.assertNotNull(restClient.post("http://sampleurl",Object.class, Object.class));
    }

答案 2 :(得分:0)

在我的WebClient代码中添加标题之后,它开始像魔术一样工作

    @Test
    public void postMethod() {
        when(webClient.post()).thenReturn(requestBodyUriMock);
        when(requestBodyUriMock.uri(anyString())).thenReturn(requestBodyMock);
        when(requestBodyMock.header(any(),any())).thenReturn(requestBodyMock);

        when(requestHeadersMock.header(any(),any())).thenReturn(requestHeadersMock);

        when(requestBodyMock.accept(any())).thenReturn(requestBodyMock);
        when(requestBodyMock.contentType(any())).thenReturn(requestBodyMock);
        when(requestBodyMock.body(any())).thenReturn(requestHeadersMock);
        when(requestHeadersMock.retrieve()).thenReturn(responseMock);
        when(responseSpec.bodyToMono(String.class))
                .thenReturn(Mono.just("output"));
    
        //WebClient call
        TestResponse test = service.testMethod(mockObject);
        assertEquals(test.Status(), 200);
    }