【问题标题】:Unit testing Armeria's decorator using context.log().whenComplete()使用 context.log().whenComplete() 对 Armeria 的装饰器进行单元测试
【发布时间】:2021-09-03 11:02:50
【问题描述】:

我有一个 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() 未来永远不会完成。我需要做些什么来确保 log() 未来最终完成?

【问题讨论】:

    标签: armeria


    【解决方案1】:

    模拟RequestLog完成

    RequestLog 由 Armeria 的网络层完成,因此仅使用 HttpRequestHttpResponse 将无法完成 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());
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-12
      • 2017-05-03
      • 2020-06-30
      • 2021-07-28
      • 2015-09-27
      • 2016-12-30
      • 1970-01-01
      • 2011-03-02
      相关资源
      最近更新 更多