New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support of MockRestServiceServer for WebClient [SPR-15286] #19852
Comments
Rossen Stoyanchev commented Indeed we'll most certainly need that. I'm putting it in the 5.1 backlog for now since I don't expect we'll manage that for 5.0. |
Rossen Stoyanchev commented In the mean time I suggest using the OkHttp MockWebServer (or similar) as do in our own WebClientIntegrationTests. |
Rob Worsnop commented OkHttp was not a good substitute for us, so we created a temporary drop-in replacement for MockRestServiceServer. It, along with supporting classes, is here: https://github.com/vmware/connectors-workspace-one/tree/master/common/connectors-test/src/main/java/com/vmware/connectors/mock Example usage here: https://github.com/vmware/connectors-workspace-one/blob/master/connectors/jira/src/test/java/com/vmware/connectors/jira/JiraControllerTests.java |
Rossen Stoyanchev commented What did you run into, i.e. where did using OkHttp fall short? |
Rob Worsnop commented Our code does a parallel scatter-gather and aggregates the results. Because OkHttp is a "real" HTTP server, we get those results in a non-deterministic order, which makes it hard to match actual results to expected results. I think I got around that by sorting the results with Flux.sort (in the production code, not tests) but then there was another problem: Our server returns JSON with hyperlinks pointing to the back-end it's accessing. With MockRestServiceServer, our code thinks it's talking to |
Rossen Stoyanchev commented Thanks for the feedback. Would JSONPath help in this scenario, i.e. dealing with data in non-deterministic order, and also parameterizing the host and port? On the flip side processing scatter gather in true random fashion probably makes for more realistic tests, which is desirable as long as it doesn't bring undue burden. |
Rob Worsnop commented I thought I could probably work around all of the issues somehow, but at some point I realized that creating a WebClient-compatible mock was going to end up being easier. |
Rossen Stoyanchev commented Good to know, thanks! |
Rob Worsnop commented Quick update: I just used WebTestClient/OkHttp on a new project. It does seem much better than MockMvc/MockRestServiceServer. One thing I noticed is that ordering in JSON arrays doesn't matter because I'm calling expectBody().json() on WebTestClient. Then I went back and noticed that we're calling content().string in the old code instead of content().json. (The reasons for doing this aren't entirely stupid, but they aren't that great either.) Now I'm wondering if rewriting the old tests using WebTestClient/OkHttp might be the best way forward, now that the old tests have confirmed that moving to WebClient hasn't broken anything. |
Rossen Stoyanchev commented It would be useful to confirm if there are any specific issues in transitioning those tests. That is if you find the time the time for that exercise :) |
Craig Skinfill commented any plans to implement this? its making adopting WebFlux and WebClient harder since we can't test the same way we could with RestTemplate |
Rossen Stoyanchev commented Craig Skinfill, given the existence of the MockWebServer and others like WireMock, the idea is we might never build a MockRestServiceServer equivalent. I realize we have work to do to make this more clear in the docs, and to add some testing support for this in Spring Boot, but as far a direction, in the absence of any compelling reasons to build our own solution, MockWebServer (or similar mock server) is the present day alternative to MockRestServiceServer. I have not done a complete analysis and comparison but it's clear that MockWebServer is in the same space and serves the same purpose, but is more widely applicable to any HTTP client, because it's exposed over HTTP through communication over a socket. So instead of using some sort of mock
|
Craig Skinfill commented Rossen Stoyanchev thanks for the explanation. that makes sense to me. Is there a preferred, from spring reactor perspective, mock server to consider? Or any that have a closer integration with spring?
Thanks again. |
Rossen Stoyanchev commented Craig Skinfill we're using MockWebServer for our own tests, and it suits our needs so far. I don't have experience with others. I think we probably need to think about Boot support for integration tests for code that uses the |
Using |
@membersound Have you used wiremock ? |
While this might work, I'd prefer relying on some kind of "official" framework, eg something that's included and maintained by spring themselves. Otherwise, if WebClient evolves by time, and WireMock is left behind, that might led to rewrites for all of my projects. As we all know, time is money, so that's too risky... |
@membersound I appreciate the point but there is also a lot of effort involved to create, maintain, and evolve something over time and it's hard to justify given the existing alternatives. HTTP provides loose coupling so implementations can exist and evolve independently. In this case we're even talking about mocking a server and shaping its behavior. I should think that switching from one to another shouldn't be as big a deal as it might seem at first. That said MockWebServer has more stars than the Spring Framework does and I don't think it is going to be a problem with longevity. |
Is it listed somewhere in the official docs that MockWebServer is the recommended solution? I've spent a few days now looking for an official Spring version or trying to get existing stuff to work and finally stumbled on this thread.. |
@bclozel I see it now...thanks. |
Closing as we have no further plans at this time. |
Stéphane Nicoll opened SPR-15286 and commented
Spring Boot has a
@RestClientTest
for pure client-side tests. We currently auto-configureMockRestServiceServer
and bind anyRestTemplate
created by theRestTemplateBuilder
to it.This would be pretty awesome if we could port that feature to
WebClient
transparently if webflux is on the classpath. That would require thatMockRestServiceServer
can be configured with aWebClient
in addition to aRestTemplate
Sub-tasks:
15 votes, 24 watchers
The text was updated successfully, but these errors were encountered: