Я бы посоветовал предоставить реактивный API, который возвращает Mono<Void>
от веб-клиента, особенно если вы назовете свой метод «sendAsync». Это не асинхронно, если вам нужно заблокировать вызов / возврат. Если вы хотите предоставить альтернативу sendSync()
, вы всегда можете вызвать ее sendAsync().block()
.
. Для преобразования исключения вы можете использовать выделенный оператор onErrorMap
.
ДляСуть в том, что вы не можете на 100% тестировать асинхронный код с чисто императивными и синхронными конструкциями (например, аннотация JUnit Test(expected=?)
). (хотя некоторые реактивные операторы не вызывают параллелизма, поэтому этот вид теста может иногда работать).
Вы также можете использовать .block()
здесь (тестирование одноиз редких случаев, когда это вряд ли будет проблематично).
Но на вашем месте я бы привык использовать StepVerifier
из reactor-test
. Чтобы привести пример, который подводит итог моих рекомендаций:
@Service
public class MyClass {
private final WebClient webClient;
public MatcherClient(@Value("${my.url}") final String myUrl) {
this.webClient = WebClient.create(myUrl);
}
public Mono<MyCustomResponse> sendAsync(String request) {
return webClient.post()
.header(HttpHeaders.CONTENT_TYPE, "application/json")
.body(BodyInserters.fromObject(request))
.retrieve()
.onErrorMap(throwable -> new CustomException(throwable.getMessage()))
//if you really need to hardcode that logging
//(can also be done by users who decide to subscribe or further add operators)
.doOnNext(response -> log.info(response));
}
}
и тест:
@Test(expected = CustomException.class)
public void testSendAsyncRethrowingException() {
MockResponse mockResponse = new MockResponse()
.setHeader(HttpHeaders.CONTENT_TYPE, "application/json")
.setResponseCode(500).setBody("Server error");
mockWebServer.enqueue(mockResponse);
//Monos are generally lazy, so the code below doesn't trigger any HTTP request yet
Mono<MyCustomResponse> underTest = matcherService.matchAsync(track);
StepVerifier.create(underTest)
.expectErrorSatisfies(t -> assertThat(t).isInstanceOf(CustomException.class)
.hasMessage(throwable.getMessage())
)
.verify(); //this triggers the Mono, compares the
//signals to the expectations/assertions and wait for mono's completion
}