【问题标题】:How to mock Spring WebClient and builder如何模拟 Spring WebClient 和构建器
【发布时间】:2021-12-19 17:58:24
【问题描述】:

我正在尝试模拟 Spring WebClient 并且遇到了 WebClient.builder() 模拟的问题。到目前为止我在测试中定义的模拟没有被使用,我认为是因为这个构建器没有返回我的模拟 WebClient。如何让 builder 退回我的模型?

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? 但没有使用模拟。如何模拟构建器/从构建器返回我的模拟?

【问题讨论】:

    标签: java spring rest unit-testing mockito


    【解决方案1】:

    您需要模拟WebClient 的静态方法builder()。事实上,如果这个方法没有被模拟,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);
        }
    }
    

    你可以测试一下。

    【讨论】:

    • MockedStatic 类型和 Mockito.mockStatic(..) 方法未使用 mockito-inline 导入。看起来他们现在在 Mockito 核心中,但是当我使用核心时,我收到一个错误,告诉我使用 mockito-inline: ``` org.mockito.exceptions.base.MockitoException: The used MockMaker PowerMockMaker does not support the创建静态模拟 Mockito 的内联模拟制造商支持基于 Instrumentation API 的静态模拟。您可以通过将“mockito-inline”工件放置在您当前使用“mockito-core”的位置来简单地启用此模拟模式。 ```
    猜你喜欢
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2022-07-06
    • 2020-07-12
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多