#spring #spring-webflux #project-reactor #spring-reactive
#spring #spring-webflux #проект-реактор #spring-реактивный
Вопрос:
Я пишу простой HTTP-сервер с Spring WebFlux, используя функциональный API в Kotlin.
Как говорится в документации, a HandlerFuction
обрабатывает входящие ServerRequest
s, возвращая a Mono<ServerResponse>
при вызове.
Предположим, у нас есть следующая функция, которая отвечает либо OK, либо BAD_REQUEST в зависимости от того, представлена ли переменная name path:
val helloHandler = HandlerFunction { req ->
try {
val name = req.pathVariable("name")
ok().bodyValue("Hello $name!")
} catch (_: IllegalArgumentException) {
badRequest().build()
}
}
Раздел тестирования справочного руководства Spring подразумевает, что эту функцию следует тестировать в сочетании с ее RouterFunction
использованием WebTestClient
. Такой тест будет выглядеть так:
val helloHandlerRouter = RouterFunctions.route()
.GET("/hello/{name}", helloHandler)
.build()
val client = WebTestClient
.bindToRouterFunction(helloHandlerRouter)
.build()
client.get().uri("/hello/Panda").exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello Panda!")
Хотя этот тест кажется удовлетворительным, он сильно зависит от базового механизма маршрутизации. Например, он вернет NOT_FOUND вместо BAD_REQUEST для отсутствующей переменной пути имени, игнорируя фактическую логику обработчика. Маршрутизатор перехватывает, просто не пересылая запрос обработчику, следовательно, следующий тест проверяет маршрутизатор, а не обработчик:
client.get().uri("/hello").exchange()
.expectStatus().isBadRequest // FAILS: NOT_FOUND != BAD_REQUEST
.expectBody().isEmpty
Как протестировать HandlerFunction
без маршрутизатора?
Я хотел бы протестировать HandlerFunction
изолированно, как-то так:
val request = MockServerRequest.builder()
.pathVariable("name", "Panda")
.build()
val response: Mono<ServerResponse> = helloHandler.handle(request).block()
// ??? verify ???
Но я не нашел достаточного способа посмотреть внутри ответа и проверить его значения.
Не могли бы вы посоветовать, как тестировать HandleFunctions
отдельно от их RouterFunctions
?
Комментарии:
1. покажите нам ту часть, где функция обработчика сопоставляется с ее URL.
2. Спасибо, @ThomasAndolf. Теперь найдите
RouterFunction
реализацию в описании.3. проблема в том, что вы предполагаете, что
/hello
и/hello/{name}
является URL-адресом, которым он не является. Это 2 отдельные конечные точки.4. Или, еще точнее
RouterFunction
, вернет пустоеMono<ServerResponse>
значение, посколькуRequestPredicate
в GET / hello не найдено совпадений. Следовательно, маршрутизатор отвечает 404 (см. Здесь ). Но это поведение все еще находится в маршрутизаторе, в то время как я намерен протестироватьHandlerFunction
.5. если вы хотите протестировать свою функцию-обработчик, вам следует использовать step verifier, а затем имитировать ваш запрос, а не использовать макет webclient