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

SpringBoot 3响应式应用WebTestClient返回404而非200求助

SpringBoot 3响应式WebTestClient测试返回404问题排查

我在测试SpringBoot(3)响应式应用的REST层时,使用Spring的WebTestClient遇到了问题:运行应用时用Postman能正常访问端点并返回200,但测试代码却持续返回404。

测试代码如下:

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = ReferenceDataApplication.class)
public class RefDataResourceTest {

    @Autowired
    private WebTestClient webTestClient;

    @BeforeEach
    void setup() {
        webTestClient = WebTestClient.bindToController(new RefDataResource()).build();
    }

    @Test
    public void shouldGetReferenceDataByTypeCode() {
        webTestClient
                .get()
                .uri("/api/projects/refData/findByCode")
                .exchange()
                .expectStatus().isOk();
    }
}

资源类实现了OpenApi生成的委托类,Spring中定义了/api/projects/作为基础路径:

@Component
public class RefDataResource implements RefDataApiDelegate {

    @Override
    public Mono<ResponseEntity<Flux<RefDataElementDTO>>> findDataByCode(String code,
                                                                              ServerWebExchange exchange) {

        return Mono.just(ResponseEntity.ok().build());
    }

}

问题原因及修复方法

  • 核心错误:手动构建WebTestClient覆盖了上下文配置
    你在@BeforeEach中用bindToController重新创建WebTestClient实例,这种方式属于孤立控制器测试,只会加载单个控制器的逻辑,不会读取Spring上下文的全局配置——比如你定义的/api/projects/基础路径、OpenApi生成的路由映射规则等。而Postman访问的是完整启动的应用,自然能匹配到正确路径。

  • 修复步骤:移除手动构建逻辑
    保留@Autowired注入的WebTestClient即可,它是基于@SpringBootTest启动的完整上下文生成的,会自动包含所有路径前缀和路由配置。修改后的测试类:

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = ReferenceDataApplication.class)
public class RefDataResourceTest {

    @Autowired
    private WebTestClient webTestClient;

    // 移除原setup方法

    @Test
    public void shouldGetReferenceDataByTypeCode() {
        webTestClient
                .get()
                .uri("/api/projects/refData/findByCode")
                .exchange()
                .expectStatus().isOk();
    }
}
  • 额外注意:参数缺失问题
    你的findDataByCode方法需要接收String code参数,但当前测试代码没有传递该参数。如果OpenApi生成的路由要求该参数(作为请求参数或路径变量),即使修复了WebTestClient的问题,仍可能返回4xx错误。需要根据实际路由规则补充参数,例如如果是请求参数:
webTestClient
        .get()
        .uri(uriBuilder -> uriBuilder
                .path("/api/projects/refData/findByCode")
                .queryParam("code", "test-demo-code")
                .build())
        .exchange()
        .expectStatus().isOk();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:12:16