如何模拟Spring WebClient和Builder

z31licg0  于 2023-04-28  发布在  Spring
关注(0)|答案(1)|浏览(129)

我试图模拟Spring WebClient,但遇到了WebClient的问题。builder()mocking.到目前为止,我在测试中定义的mock没有被使用,我想是因为这个构建器没有返回我的mock WebClient。我怎样才能让建筑商归还我的模拟模型?

WebClient webClient = WebClient.builder()
                .exchangeStrategies(ExchangeStrategies.builder()
                .codecs(configurer -> configurer
                        .defaultCodecs()
                        .maxInMemorySize(16 * 1024 * 1024))
                .build())
                .clientConnector(new ReactorClientHttpConnector(HttpClient.newConnection().compress(true)))
                .build();

WebClient的使用方法如下:

response = webClient
            .get()
            .uri(URLDecoder.decode(someEndpoint.replace("\"", ""), CLIENT_ENCODING))
            .header(AUTHORIZATION, BEARER + accessToken)
            .accept(MediaType.APPLICATION_JSON)
            .retrieve().bodyToMono(JsonNode.class).block();

我没有看到任何问题的模拟,因为我遵循这些解决方案:How to mock Spring WebFlux WebClient?,但未使用模拟。我怎样才能模仿构建器/从构建器返回我的模仿?

fkaflof6

fkaflof61#

您需要模拟WebClient的静态方法builder()。实际上,如果这个方法没有被mockito模仿,mockito就不能编辑这个方法的行为。因此,您的模拟webClient不会被使用。要实现这一点,如果你使用maven,你需要在pom.xml中包含这个依赖项。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.4.6</version>
    <scope>test</scope>
</dependency>

这将在Mockito上提供mockStatic()方法,可以像这样使用:

MockedStatic<WebClient> webClientStatic = Mockito.mockStatic(WebClient.class);
webClientStatic.when(WebClient::builder).thenReturn(webClientBuilder);

必须模拟webClientBuilder,因为我们需要更改其方法build()的行为以返回模拟的webClient。

Mockito.when(webClientBuilder.build()).thenReturn(mockedWebClient);

要在一个代码中恢复所有内容,请执行以下操作:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import org.mockito.MockedStatic;

@RunWith(MockitoJUnitRunner.class)
public class WebClientTest {

    @Mock
    private WebClient.Builder webClientBuilder;

    @Mock
    private WebClient mockedWebClient;

    @Before
    public void setup() {
        Mockito.when(webClientBuilder.exchangeStrategies(Mockito.any(ExchangeStrategies.class))).thenReturn(webClientBuilder);
        Mockito.when(webClientBuilder.clientConnector(Mockito.any(ReactorClientHttpConnector.class))).thenReturn(webClientBuilder);
        Mockito.when(webClientBuilder.build()).thenReturn(mockedWebClient);
    }

    @Test
    public void testWebClient() {
        final MockedStatic<WebClient> webClientStatic = Mockito.mockStatic(WebClient.class);
        webClientStatic.when(WebClient::builder).thenReturn(webClientBuilder);

        final WebClient webClient = WebClient.builder()
                .exchangeStrategies(ExchangeStrategies.builder()
                        .codecs(configurer -> configurer
                                .defaultCodecs()
                                .maxInMemorySize(16 * 1024 * 1024))
                        .build())
                .clientConnector(new ReactorClientHttpConnector(HttpClient.newConnection().compress(true)))
                .build();

        //It throws error if webClient is not mockedWebClient
        Assert.assertEquals(webClient, mockedWebClient);
    }
}

你可以测试一下。

相关问题