【问题标题】:Mocking WebClient post method is failing模拟 WebClient 发布方法失败
【发布时间】:2022-08-17 11:27:13
【问题描述】:

我可以找到几个关于模拟 WebClient 对象的问题。但是在使用正文和具有多个标题值的帖子时,我仍然遇到问题。我只是在使用 Mockito。

public Boolean addNote(AlarmModel model) {
        ServiceDTO dto = mapper(model);

        return webClient.post()
                .uri(\"/service/api/addNotes\")
                .headers(getHttpHeaders(dto.getHeader()))
                .accept(MediaType.APPLICATION_JSON)
                .body(Mono.just(dto.getBody()), ServiceBodyDTO.class)
                .retrieve()
                .onStatus(HttpStatus::is5xxServerError, this::handleStatusCodeError)
                .onStatus(HttpStatus::is4xxClientError, this::handleStatusCodeError)
                .bodyToMono(Boolean.class)
                .block();
    }

这就是我嘲笑 post 方法行为的方式。

        when(webClientMock.post()).thenReturn(requestBodyUriMock);
        when(requestBodyUriMock.uri(anyString())).thenReturn(requestBodyMock);
        
        when(requestHeadersMock.headers(any())).thenReturn(requestHeadersMock);

        when(requestBodyMock.accept(any())).thenReturn(requestBodyMock);
        when(requestBodyMock.contentType(any())).thenReturn(requestBodyMock);
        when(requestBodyMock.bodyValue(any())).thenReturn(requestHeadersMock);
        when(requestHeadersMock.retrieve()).thenReturn(responseMock);
        when(responseMock.bodyToMono(Boolean.class))
                .thenReturn(Mono.just(true));

但是,当我执行这个测试用例时,它在以下行失败了取回()例外是java.lang.NullPointerException

我在这里错过了什么吗? TIA。

  • 是的,我已经检查过了。我需要为此进行集成测试。我正在尝试进行单元测试。
  • 单元测试 webclient 的 ROI 非常低,它的 API 不是为此而设计的,你最好只进行集成测试

标签: java mockito spring-webflux


【解决方案1】:

同意@Martin 的评论单元测试 webclient 的 ROI 非常低。

我会推荐WireMock,它为测试Web 客户端提供了非常好的API。这里有些例子

stubFor(post("/service/api/addNotes")
        .withHeader(HttpHeaders.ACCEPT, containing(MediaType.APPLICATION_JSON_VALUE))
        .willReturn(aResponse()
                .withStatus(200)
                .withBody("true")
        )
);

StepVerifier.create(service.addNote(note))
        .expectNextCount(1)
        .verifyComplete();

您可以通过提供不同的存根轻松地测试正面和负面情况

stubFor(post("/service/api/addNotes")
        .withHeader(HttpHeaders.ACCEPT, containing(MediaType.APPLICATION_JSON_VALUE))
        .willReturn(aResponse()
                .withStatus(500)
        )
);

使用Scenarios 测试重试逻辑,甚至使用Delays 模拟超时

ps

不知道你为什么使用block 但我的例子是使用StepVerifier 并假设addNote 返回Mono<Boolean>

【讨论】:

    【解决方案2】:

    这对我有用,和你的没什么不同。您可能想要比较和反馈:)

    @Mock
    private WebClient webClient;
    
    @Mock
    WebClient.RequestBodyUriSpec requestBodyUriSpec;
    
    @SuppressWarnings("rawtypes")
    @Mock
    WebClient.RequestHeadersSpec requestHeadersSpec;
    
    @Mock
    WebClient.RequestBodySpec requestBodySpec;
    
    @Mock
    WebClient.ResponseSpec responseSpec;
    
    given(getWebClient()).willReturn(webClient);
    given(webClient.post()).willReturn(requestBodyUriSpec);
    given(requestBodyUriSpec.uri(anyString())).willReturn(requestBodySpec);
    given(requestBodySpec.headers(any())).willReturn(requestBodySpec);      
    given(requestBodySpec.contentType(any())).willReturn(requestBodySpec);
    given(requestBodySpec.accept(any())).willReturn(requestBodySpec);
    given(requestBodySpec.bodyValue(any())).willReturn(requestHeadersSpec);
    given(requestHeadersSpec.retrieve()).willReturn(responseSpec);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多