Rx java 如何测试SpringWebClient,何时重试?

Rx java 如何测试SpringWebClient,何时重试?,rx-java,reactive-programming,project-reactor,spring-webclient,Rx Java,Reactive Programming,Project Reactor,Spring Webclient,我需要实现以下行为: 提出一个RESTPOST请求 如果响应返回时状态为“429太多请求”,请以1秒的延迟重试最多3次 如果第三次重试失败或发生任何其他错误,请记录日志并向数据库写入内容 如果请求成功(http状态200),则记录一些信息 为此,我想使用Spring WebClient,并产生了以下代码: Mono<ClientResponse> response = webClient.post() .uri(URI.create("/myuri"))

我需要实现以下行为:

  • 提出一个RESTPOST请求
  • 如果响应返回时状态为“429太多请求”,请以1秒的延迟重试最多3次
  • 如果第三次重试失败或发生任何其他错误,请记录日志并向数据库写入内容
  • 如果请求成功(http状态200),则记录一些信息
为此,我想使用Spring WebClient,并产生了以下代码:

Mono<ClientResponse> response = webClient.post()
            .uri(URI.create("/myuri"))
            .body(BodyInserters.fromObject(request))
            .retrieve()
            .onStatus(httpStatus -> httpStatus.equals(HttpStatus.TOO_MANY_REQUESTS), 
                      response -> Mono.error(new TooManyRequestsException("System is overloaded")))
            .bodyToMono(ClientResponse.class)
            .retryWhen(Retry.anyOf(TooManyRequestsException.class)
                                          .fixedBackoff(Duration.ofSeconds(1)).retryMax(3))
            .doOnError(throwable -> saveToDB(some_id, throwable))
            .subscribe(response -> logResponse(some_id, response));
Mono response=webClient.post()
.uri(uri.create(“/myuri”))
.body(BodyInserters.fromObject(请求))
.retrieve()
.onStatus(httpStatus->httpStatus.equals(httpStatus.TOO\u多个请求),
响应->单声道错误(新的TooManyRequestsException(“系统过载”))
.bodyToMono(ClientResponse.class)
.retryWhen(Retry.anyOf(TooManyRequestsException.class)
.fixedBackoff(持续时间秒(1)).retryMax(3))
.doon错误(可丢弃->保存到数据库(某些id,可丢弃))
.subscribe(response->logResponse(some_id,response));

现在我想测试重试机制和错误处理是否如我所期望的那样工作。也许我可以用它来达到这个目的,但我就是不知道如何在我的案例中使用它。有什么有用的提示吗?

我认为您可以使用模拟web服务器来测试这一点,例如

@测试
public void testReactiveWebClient()引发IOException
{
MockWebServer MockWebServer=新建MockWebServer();
String expectedResponse=“期望它能工作”;
enqueue(新的MockResponse().setResponseCode(429));
enqueue(新的MockResponse().setResponseCode(429));
enqueue(新的MockResponse().setResponseCode(429));
mockWebServer.enqueue(新的MockResponse().setResponseCode(200)
.setBody(预期响应);
mockWebServer.start();
HttpUrl=mockWebServer.url(“/mvuri”);
WebClient WebClient=WebClient.create();
Mono responseMono=webClient.post()
.uri(url.uri())
.body(BodyInserters.fromObject(“myRequest”))
.retrieve()
onStatus先生(
httpStatus->httpStatus.equals(httpStatus.TOO_MANY_REQUESTS),
response->Mono.error(新TestStuff.TooManyRequestsException(“系统过载”))
.bodyToMono(String.class)
.retryWhen(Retry.anyOf(TestStuff.TooManyRequestsException.class)
.fixedBackoff(持续时间为秒(1)).retryMax(3));
StepVerifier.create(响应编号)
.expectNext(expectedResponse)
.expectComplete().verify();
mockWebServer.shutdown();
}

如果您使用statuscode
429
将另一个
MockResponse
排队,验证将失败,例如errorcode
500

多米尼克·桑贾亚的回答基本上帮助我设置了测试。为了完整起见,我在这里发布了工作版本:

@Test
public void mytest() {
    MockResponse mockResponse = new MockResponse()
        .setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
        .setResponseCode(429).setBody("Too many requests");
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);

    Mono<MyClass> responseMono = methodDoingTheAsyncCall.sendAsync(...);
    StepVerifier.create(responseMono)
                .expectError(RetryExhaustedException.class)
                .verify();
}
@测试
公共无效mytest(){
MockResponse MockResponse=新的MockResponse()
.setHeader(HttpHeaders.CONTENT_类型,“application/json”)
.setResponseCode(429).setBody(“请求太多”);
mockWebServer.enqueue(mockResponse);
mockWebServer.enqueue(mockResponse);
mockWebServer.enqueue(mockResponse);
mockWebServer.enqueue(mockResponse);
Mono responseMono=methodDoingTheAsyncCall.sendAsync(…);
StepVerifier.create(响应编号)
.expectError(RetryExhaustedException.class)
.verify();
}
@Test
public void mytest() {
    MockResponse mockResponse = new MockResponse()
        .setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
        .setResponseCode(429).setBody("Too many requests");
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);
    mockWebServer.enqueue(mockResponse);

    Mono<MyClass> responseMono = methodDoingTheAsyncCall.sendAsync(...);
    StepVerifier.create(responseMono)
                .expectError(RetryExhaustedException.class)
                .verify();
}