不使用WebTestClient,如何单元测试Spring Reactive Handler POST方法?
问题:不使用WebTestClient测试Spring Reactive Handler的POST方法
需求:在不使用WebTestClient的情况下,对Spring Reactive的Handler POST方法进行单元测试。
已编写的模拟ServerRequest代码如下:
//Mocked serverRequest like below MockServerRequest serverRequest = MockServerRequest.builder() .method(HttpMethod.POST) .header(AUTHORIZATION_HEADER, params.get(AUTHORIZATION_HEADER)) .body(Mono.just(myUserRequest)); //Tried to verify like below, not working StepVerifier.create(userHandler.postUserData(serverRequest)) .assertNext(serverResponse -> assertEquals("testuser", getEntity(serverResponse).getUserId())) .verifyComplete(); private static UserResponse getEntity(ServerResponse serverResponse) { return ((EntityResponse<UserResponse>) serverResponse).entity(); }
尝试上述验证代码无效,出现报错:
class reactor.core.publisher.MonoJust cannot be cast to class com.mypackage.user.model.UserResponse
解决方案
问题根源
你的getEntity方法错误地将EntityResponse的entity()返回值强制转换为UserResponse,但实际上当响应体是Mono<UserResponse>时,entity()返回的是Mono<UserResponse>类型,而非直接的UserResponse对象,这导致了类型转换异常。
修正方法
你有两种可行的修正方式:
方式一:修改getEntity方法,从Mono中提取实际对象
单元测试场景下可以安全使用block()来获取Mono中的值:
private static UserResponse getEntity(ServerResponse serverResponse) { // 注意泛型是Mono<UserResponse> EntityResponse<Mono<UserResponse>> entityResponse = (EntityResponse<Mono<UserResponse>>) serverResponse; return entityResponse.entity().block(); }
方式二:在StepVerifier中嵌套验证Mono响应体
保持响应式风格,不使用block(),通过嵌套StepVerifier验证内部的Mono:
StepVerifier.create(userHandler.postUserData(serverRequest)) .assertNext(serverResponse -> { EntityResponse<Mono<UserResponse>> entityResponse = (EntityResponse<Mono<UserResponse>>) serverResponse; // 验证响应体中的Mono内容 StepVerifier.create(entityResponse.entity()) .assertNext(userResponse -> assertEquals("testuser", userResponse.getUserId())) .verifyComplete(); }) .verifyComplete();
额外提示
如果你的Handler中使用了ServerResponse.ok().bodyValue(userResponse)(直接传入对象而非Mono),那entity()返回的才是UserResponse。但通常Reactive场景下会返回Mono<UserResponse>,所以要根据实际情况调整类型转换的泛型。
内容的提问来源于stack exchange,提问作者ElephantLove
相关产品推荐
相关产品推荐

