You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 11:03:22