Testing Spring WebClient with MockWebServer
Spring Boot offers many convenience classes to simplify common test cases.
For testing HTTP client code (testing a RestTemplate
as opposed to testing a RestController
),
we can use the MockRestServiceServer
in conjunction with the @RestClientTest
annotation to mock a third party Web
API.
// Testing with Spring Web and RestTemplate
@RestClientTest(TodoService.class)
class ExampleRestClientTest {
@Autowired
private TodoService service;
@Autowired
private MockRestServiceServer server;
@Test
void shouldReturnTodos() throws Exception {
this.server.expect(requestTo("/todos")).andRespond(withSuccess("[]", MediaType.APPLICATION_JSON_VALUE));
Collection<Todo> todos = this.service.fetchTodos();
assertThat(todos).hasSize(0);
}
}
This is well documented in the Spring Boot Reference Documentation.
Unfortunately the RestClientTest
only supports RestTemplate
, but not WebClient
and thus cannot be used in a
reactive Spring WebFlux application.
The recommended alternative for WebFlux is the use of a mock web server provided by the OkHttp library.
The setup is only slightly more complex than before:
// Testing with Spring WebFlux and WebClient
class TodoServiceTest {
private static MockWebServer mockWebServer;
private static TodoService todoService;
@BeforeAll
static void beforeAll() {
mockWebServer = new MockWebServer();
todoService = new TodoService(WebClient.builder(), mockWebServer.url("/").url());
}
@AfterAll
static void afterAll() throws IOException {
mockWebServer.close();
}
@Test
void shouldReturnTodoDtos() {
mockWebServer.enqueue(
new MockResponse()
.setResponseCode(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody("[]")
);
assertThat(this.todoService.findTodos().collectList().block()).isEqualTo(Collections.emptyList());
}
}
The full source code for this example is available in this Github project.