Spring webflux,正在测试“ServerResponse”
Spring webflux, testing `ServerResponse`
如何测试接收 ServerRequest
和 return Mono<ServerResponse>
的 handler 方法?
我可以通过 org.springframework.mock.web.reactive.function.server.MockServerRequest.builder()
创建一个 ServerRequest
。并在 ServerResponse.statusCode()
上断言。但是我想测试这个 ServerResponse
的主体,但是没有办法提取它。
ServerResponse response = target.search(MockServerRequest.builder()
.method(HttpMethod.GET)
.build()
).block();
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
//assertThat(response.body()).isNotNull();
我不想用 WebTestClient
做更广泛的测试,我想用单元测试测试所有可能的响应情况。
谢谢
所以,最好的解决办法似乎是使用WebTestClient
。然而,这个可以在没有 运行 服务器的情况下使用;
The spring-test
module includes a WebTestClient
that can be used to test WebFlux server endpoints with or without a running server.
诀窍是使用 bindTo..()
构建器方法。在我的例子中 bindToRouterFunction(new MyRouter(new MyHandler()))
效果很好
我有完全相同的问题,因为我不想为每个测试启动整个 Spring 上下文。感谢您自己回答中的信息,这对我有帮助。这是一个包含 Mockito 和 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("{}");
}
}
我问了一个 similar question 坚持不使用 WebTestClient。
在发现可以将响应转换为允许检查主体(实体)的类型后,我最终回答了我自己的问题。
魔法线 (Kotlin) 是:
(serverResponse as EntityResponse<Fleet>).entity()
编辑:
所以对于期望一个空体的情况,你可以这样做:
assert(serverResponse !is EntityResponse<*>)
感谢@andred 指出这一点
如何测试接收 ServerRequest
和 return Mono<ServerResponse>
的 handler 方法?
我可以通过 org.springframework.mock.web.reactive.function.server.MockServerRequest.builder()
创建一个 ServerRequest
。并在 ServerResponse.statusCode()
上断言。但是我想测试这个 ServerResponse
的主体,但是没有办法提取它。
ServerResponse response = target.search(MockServerRequest.builder()
.method(HttpMethod.GET)
.build()
).block();
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
//assertThat(response.body()).isNotNull();
我不想用 WebTestClient
做更广泛的测试,我想用单元测试测试所有可能的响应情况。
谢谢
所以,最好的解决办法似乎是使用WebTestClient
。然而,这个可以在没有 运行 服务器的情况下使用;
The
spring-test
module includes aWebTestClient
that can be used to test WebFlux server endpoints with or without a running server.
诀窍是使用 bindTo..()
构建器方法。在我的例子中 bindToRouterFunction(new MyRouter(new MyHandler()))
效果很好
我有完全相同的问题,因为我不想为每个测试启动整个 Spring 上下文。感谢您自己回答中的信息,这对我有帮助。这是一个包含 Mockito 和 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("{}");
}
}
我问了一个 similar question 坚持不使用 WebTestClient。 在发现可以将响应转换为允许检查主体(实体)的类型后,我最终回答了我自己的问题。
魔法线 (Kotlin) 是:
(serverResponse as EntityResponse<Fleet>).entity()
编辑: 所以对于期望一个空体的情况,你可以这样做:
assert(serverResponse !is EntityResponse<*>)
感谢@andred 指出这一点