During Spring Boot 2.2 upgrade (from 2.1.x) we've noticed regression in tests using webclient.
Scenario: Call an enpoint returning 404 NOT_FOUND (with non-empty response body)
Expected: webclient returns empty Mono instance
spring-webflux >= 5.2.0 Actual: webclient call returns an non-empty response but the wrapped object has nothing more than nulls inside - unit test fails.
spring-webflux == 5.1.14 Actual: webclient call returns an empty response - unit test works fine.
Here is a sample that reproduces the problem: https://github.com/jmayday/emptymono Please have a look at this unit test (it uses Wiremock) - shouldReturnEmptyObjectFor404WithResponseBody
Unit test result:
java.lang.AssertionError:
Expecting an empty Optional but was containing value: <MyEntity(id=null, name=null, owner=null)>.
Pay attention, that if we'll modify response body in wiremock mapping and replace body
{"error_code":404,"message":"Page not found"}
with empty body, then test will work.
Is this a spring-webflux 5.2.x regression or I'm misusing it?
Comment From: snicoll
@jmayday thanks for the report but in order to understand what's going on we'll have to copy all that text in a project we can run from an IDE. Can you please edit your description without the text and a link to a github repo (or a zip we can download)?
Comment From: jmayday
@snicoll OK please give me 10 minutes
Comment From: jmayday
https://github.com/jmayday/emptymono
Comment From: snicoll
@jmayday thanks. I've edited your comment with the link to your sample to make the original description more readable.
Comment From: wilkinsona
Thanks for the sample. The test that is failing isn't making any use of Spring Boot. It's purely Spring Framework's WebClient communicating with a WireMock server. We'll transfer this to the Framework team so that they can take a look.
Comment From: rstoyanchev
I believe this is due to https://github.com/spring-projects/spring-framework/commit/a9b3d95a14c316387f2b77328d6864b8e0a36721. As explained in the commit message (and Javadoc) an empty Mono effectively suppresses the error, and the bodyToMono tries to map the error JSON to the normal response Object, which results in null values.
I think the Javadoc could use some improvement. That aside, @poutsma what is your thought on the best way to achieve the effect of "no result", i.e. complete empty? Clearly that needs to be explained as well in the Javadoc as it is a valid case.
Comment From: poutsma
I think you'd have to use an ExchangeFilterFunction to accomplish this. The onStatus handlers are designed to map to an exception; not to an alternative (empty) result.
As said in the commit message, returning an empty result prior to a9b3d95 (eg 5.1.14) will actually leak memory (i.e. the body), so it never "worked" correctly in the first place.
Comment From: rstoyanchev
@jmayday see the updated to the Javadoc in the referenced commit above. I've clarified the various cases and provides suggestions for your case.
Comment From: jmayday
Thank you.