Spring webflux, testing `ServerResponse`

2020-03-03 05:22发布

问题:

How can I test a handler method that receive ServerRequest and return Mono<ServerResponse> ?

I can create a ServerRequest via org.springframework.mock.web.reactive.function.server.MockServerRequest.builder(). And assert on the ServerResponse.statusCode(). However I would like to test the body of this ServerResponse but there is no way to extract it.

ServerResponse response = target.search(MockServerRequest.builder()
    .method(HttpMethod.GET)
    .build()
  ).block();

assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
//assertThat(response.body()).isNotNull();

I don't want to do a broader test with the WebTestClient, I would like to test all possible cases of response with unit tests.

Thanks

回答1:

So, it seems that the best solution is to use the WebTestClient. However this one can be used without a running server;

The spring-test module includes a WebTestClient that can be used to test WebFlux server endpoints with or without a running server.

-- https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html#web-reactive-tests

The trick is to use the bindTo..() builder method. In my case bindToRouterFunction(new MyRouter(new MyHandler())) works well



回答2:

I had exactly the same question, because I don't want to start the entire Spring context for every test. Thanks for the info in the own-answer, this helped me. Here is a complete example including Mockito and JUnit5:

import java.util.Arrays;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;

@ExtendWith(MockitoExtension.class)
class UsersHandlerTest {
  @Mock
  UserRepository userRepository;

  WebTestClient client;

  @BeforeEach
  public void setUp() {
    UsersHandler usersHandler = new UsersHandler(userRepository);
    Router router = new Router(usersHandler);

    Mockito.when(userRepository.findAll()).thenReturn(
      Arrays.asList("", ""));

    client = WebTestClient.bindToRouterFunction(router.getUsers()).build();
  }

  @Test
  public void getCommands() {
    client.get().uri("/users")
      .accept(MediaType.APPLICATION_JSON_UTF8)
      .exchange()
      .expectStatus().isOk()
      .expectBody().json("{}");
  }
}