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

MockServerRequest测试出现The mapper returned a null Mono错误求助

解决MockServerRequest测试中"The mapper returned a null Mono"空指针问题

问题背景

我在测试一个Handler方法时,通过以下方式创建MockServerRequest对象:

MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.put("/rest/v1/templates/{id}", "1")
    .headers(headers)
    .contentType(MediaType.APPLICATION_JSON)
    .body(builder.build().writeValueAsString(templateRequest)));

MockServerHttpResponse response = exchange.getResponse();

ServerRequest request = MockServerRequest.builder().uri(URI.create("/rest/v1/templates"))
.pathVariable("id", "1").headers(headers).exchange(exchange).body(Mono.just(templateRequest));  

采用这种方式是因为,用下面的方式创建的对象无法获取路径变量,导致方法执行失败:

ServerRequest request = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());

该问题属于已知问题。

之后我将这个MockServerRequest传入Handler执行:

Mono<ServerResponse> putResponse = templateHandler.update(request);

StepVerifier.create(putResponse).expectComplete().log().verify();

但触发了如下错误:

java.lang.AssertionError: expectation "expectComplete" failed (expected: onComplete(); actual: onError(java.lang.NullPointerException: The mapper returned a null Mono))

...(完整错误栈内容同上)

解决方法

1. 排查Handler实现中的null Mono返回问题

这个错误的核心原因是templateHandler.update方法的某个分支返回了null,而非合法的Mono<ServerResponse>对象。你需要检查update方法的所有代码路径:

  • 确保所有条件分支都返回有效的Mono,比如找不到资源时返回ServerResponse.notFound().build(),出现业务异常时返回Mono.error(new RuntimeException("...")),绝对不能直接返回null。

2. 修正MockServerRequest的构建逻辑

你手动构建request时存在两处潜在问题:

  • URI不匹配:原始请求的URI是带占位符的/rest/v1/templates/{id},但你构建request时用了/rest/v1/templates,即使手动设置了pathVariable,也可能导致Handler内部路径匹配逻辑出错。建议改为具体的URI:/rest/v1/templates/1。
  • 重复设置请求体:exchange已经包含了请求体内容,无需手动通过.body(Mono.just(templateRequest))注入,这会导致request读取body时出现冲突。

修改后的构建代码:

ServerRequest request = MockServerRequest.builder()
    .uri(URI.create("/rest/v1/templates/1"))
    .pathVariable("id", "1")
    .headers(headers)
    .exchange(exchange)
    .build();

3. 调整StepVerifier断言逻辑

Mono<ServerResponse>会先发出一个响应元素,然后才会触发完成信号。你之前只用expectComplete()会忽略响应元素,可能掩盖问题,建议修改为验证响应状态:

StepVerifier.create(putResponse)
    .expectNextMatches(response -> response.statusCode().is2xxSuccessful())
    .expectComplete()
    .log()
    .verify();

4. 升级Spring Framework版本解决路径变量问题

你遇到的路径变量无法获取的问题是旧版本的已知问题,已经在后续Spring Framework版本中修复。建议升级到5.3.x及以上版本,这样就可以用标准方式创建ServerRequest,避免手动构建的潜在风险:

ServerRequest request = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());

内容的提问来源于stack exchange,提问作者Anadi Misra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:53:13