当前位置: 首页 > 知识库问答 >
问题:

如何模拟Spring WebClient和builder

年健
2023-03-14

我试图模拟Spring WebClient,并且在WebClient.builder()模拟中遇到问题。到目前为止,我在测试中定义的模拟没有被使用,我想是因为这个构建器没有返回我的模拟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();

当我遵循这些解决方案时,我没有看到模拟有任何问题:如何模拟Spring WebFlux WebClient?但是模拟没有被使用。我如何模拟构建器/从构建器返回我的模拟?

共有1个答案

隆兴修
2023-03-14

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

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

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

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);
    }
}

你可以测试一下。

 类似资料:
  • 在我的views.py中,我有一个函数,它每次使用不同的响应来调用各种requests.get() 在我的测试类中,我想做这样的事情,但无法计算出确切的方法调用 步骤1: 验证响应包含“a response”、“b response”、“c response” 如何完成步骤1(模拟请求模块)?

  • 我正在尝试使用Web客户端创建REST调用 我只想记录通话结果。成功时 - 使用响应正文记录成功消息,在 5XX 或超时或其他时 - 记录错误消息。日志应该在后台创建(而不是由创建调用的线程创建)但是每次都会执行,工作正常,但也有 记录在日志文件中。 我也在一些教程中看到过方法,但在我的设置中有这样的方法。 如何记录成功和失败消息?

  • CacheController.Somemethod();但是当submit方法被称为submit方法时,它会创建一个线程和cacheController.somemethod();从不调用测试类。

  • 当我运行测试时,我可以做什么来更改时间

  • null 我看过其他几个类似的问题,但没有一个有帮助: 模拟包含对SQLiteOpenHelper引用的类时出错 使用mockito库在java中模拟最终类-我在导入PowerMock时遇到了很多问题 如何用mockito模拟最后一个类-我已经添加了依赖项,并用行创建了文件,正如答案中所建议的那样,我仍然得到同样的错误。我还尝试了建议的答案,但这给了我一个‘没有足够的信息来推断类型变量t'erro

  • 我的要求是测试这段代码,更重要的是测试序列化器,因此,给出一个JSON片段,我如何测试所有的值都正确地通过商人的实例。 我不知道RestTemplate使用哪个序列化器将JSON序列化为对象。