久々に Spring WebFlux を書いてたのだが、いまいちルーティングがうまくできず、 Routing Function に対してテストを書いてみることにした。
で、テストの書き方を調べてみたのだが、とりあえず何も見つからなかった(サーバーを起動するパターンは見つかったが、ルーターのテストごときでサーバーを起動したくない)ので、Reactor のテストの書き方をもとに強引に書いてみた。これが正しいのかどうかはわからない。
プロダクションコード
プロダクションコードはこんな感じ。
@Configuration class Routing { private final MyHandler handler; Routing(final MyHandler handler) { this.handler = handler; } @Bean RouterFunction<ServerResponse> routerFunction() { return routes(GET("/foo"), handler::handle); } }
テストコード
で、書いたテストコード。これはあくまでルーティングが意図したものになっているかを確認するテスト。というのも、ルーティングがうまくできていなかったからテストを書いたため。
@ExtendWith(SpringExtension.class) @Import({Routing.class, MyHandler.class}) class RoutingTest { final Routing routing; @Autowired RoutingTest(final Routing routing) { this.routing = routing; } @Test void test() { final ServerRequest request = MockServerRequest.builder() .method(HttpMethod.GET) .uri(URI.create("/foo")) .build(); final Mono<HandlerFunction<ServerResponse>> handler = routing .routerFunction() .route(request); StepVerifier.create(handler) .expectNextCount(1) .verifyComplete(); } }
なお、 URI
については、かなりゆるい URI
でもマッチする。具体的には http://bar-baz/foo
でもマッチする。当然、 /foo/baz
はマッチしない。ちなみに、マッチしない場合のテストの書き方はこんな感じ。
StepVerifier.create(handler) .verifyComplete();
余談、というか…
もともとは、パスに対して正規表現でマッチングする方法を調べてた。最初うまくできなかったが、次のようにやればよいらしい。
return route(GET("/{foo:[a-zA-Z0-9]+}"), handler::handle);