Модульное тестирование декоратора Armeria с помощью context.log(). WhenComplete()
У меня есть подкласс
SimpleDecoratingHttpService
который содержит что-то вроде этого:
override fun serve(ctx: ServiceRequestContext, req: HttpRequest): HttpResponse {
ctx.log().whenComplete().thenAccept {
if (it.responseCause() == ...) {
// do stuff
}
}
return unwrap().serve(ctx, req)
}
Я хочу проверить логику внутри
whenComplete()
Перезвоните. Однако при написании таких тестов:
myDecorator.serve(context, request).aggregate().join()
будущее никогда не завершится. Что мне нужно сделать, чтобы убедиться, что
log()
будущее в конце концов завершается?
1 ответ
Эмуляция завершения
A дополняется сетевым уровнем Armeria, поэтому просто потребляя
HttpRequest
или же
HttpResponse
не завершит
RequestLog
. Для его завершения вам нужно вызвать методы в
RequestLogBuilder
:
var myDecorator = new MySimpleDecoratingHttpService(...);
var ctx = ServiceRequestContext.of(
HttpRequest.of(HttpMethod.GET, "/hello"));
var req = ctx.request();
var res = myDecorator.serve(ctx, ctx.req).aggregate().join();
// Fill the log.
ctx.logBuilder().endRequest();
assert ctx.log().isRequestComplete();
ctx.logBuilder().responseHeaders(ResponseHeaders.of(200));
ctx.logBuilder().endResponse();
assert ctx.log().isComplete();
Команда Armeria использует ту же технику для тестирования
BraveService
, так что вы можете также проверить это на BraveServiceTest.java:161.
Тестирование на реальном сервере
Если ваша установка слишком сложна для использования имитации, в качестве альтернативного подхода вы можете запустить настоящий сервер Armeria, чтобы Armeria заполнила журнал за вас. Вы можете легко запустить сервер, используя
ServerRule
(JUnit 4) или
ServerExtension
(JUnit 5):
class MyJUnit5Test {
static final var serviceContexts =
new LinkedBlockingQueue<ServiceRequestContext>();
@RegisterExtension
static final var server = new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service("/hello", (ctx, req) -> HttpResponse.of(200));
sb.decorator(delegate -> new MySimpleDecoratingHttpService(delegate, ...));
// Record the ServiceRequestContext of each request.
sb.decorator((delegate, ctx, req) -> {
serviceContexts.add(ctx);
return delegate.serve(ctx, req);
});
}
};
@BeforeEach
void clearServiceContexts() {
serviceContexts.clear();
}
@Test
void test() {
// Send a real request.
var client = WebClient.of(server.httpUri());
var res = client.get("/hello").aggregate().join();
// Get the ServiceRequestContext and its log.
var ctx = serviceContexts.take();
var log = sctx.log().whenComplete().join();
// .. check `log` here ..
assertEquals(200, log.responseHeaders().status().code());
}
}