使用@WebFluxTest测试RouterFunction时Spock测试返回404问题排查
Hey there! Let's break down why your RouterFunction test is throwing a 404 while your RestController tests work smoothly. Here are the most common issues and fixes to check:
1. Your RouterFunction isn't registered in the test context
Unlike @RestController beans (which get auto-scanned via @ComponentScan), RouterFunctions don't register themselves automatically. You need to explicitly tell the test context about your router configuration:
- Option 1: Import your router config class directly in the test:
@SpringBootTest @Import(YourRouterConfiguration.class) // 导入包含RouterFunction @Bean的配置类 class RouterFunctionSpec extends Specification { // Test code here } - Option 2: Bind the RouterFunction directly to
WebTestClient(bypasses the full Spring context for faster isolated testing):def "test my router endpoint"() { given: def webTestClient = WebTestClient.bindToRouterFunction(new YourRouter().yourRouterFunction()).build() when: def response = webTestClient.get().uri("/your/endpoint/path").exchange() then: response.expectStatus().isOk() }
2. URI path mismatch
Double-check that the path in your test exactly matches what's defined in the RouterFunction. Even tiny differences (like extra/missing slashes, case sensitivity, or incorrect path variables) will trigger a 404:
- Example: If your router uses
route(GET("/api/users/{userId}"), ...), your test must call"/api/users/123"(not"/api/users"or"/API/Users/123").
3. Request method mismatch
Spring WebFlux returns 404 (not 405) when the HTTP method doesn't match the router definition. So if your router defines a POST endpoint but your test sends a GET request, you'll get a 404.
- Verify that your test uses the same HTTP method (GET/POST/PUT/DELETE) as your RouterFunction.
4. RouterFunction bean isn't being created
If you defined your RouterFunction as a @Bean in a configuration class, make sure:
- The configuration class has the
@Configurationannotation. - The configuration class is within the component scan scope of your test, or explicitly imported (as mentioned in point 1).
- No typos in the bean method name or router definition.
5. WebTestClient configuration issues
If you're using @SpringBootTest with the default WebTestClient, it connects to the full application server. If your RouterFunction isn't registered in the main application context (e.g., it's only in a test config), the server won't know about it. Using bindToRouterFunction (as shown in point 1) is a quick way to isolate the test to just your router logic.
内容的提问来源于stack exchange,提问作者lapots

