代码之家  ›  专栏  ›  技术社区  ›  toolkit

JUnit 5中的Micronaut异常处理程序

  •  0
  • toolkit  · 技术社区  · 3 年前

    与运行JUnit测试时相比,我在运行micronaut时看到了不同的行为。

    我已经创建了一个测试控制器:

    package com.testing;
    
    import io.micronaut.http.annotation.Controller;
    import io.micronaut.http.annotation.Get;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @Controller("/test")
    public class TestController {
    
        private static final Logger log = LoggerFactory.getLogger(TestController.class);
    
        @Get("/throw")
        public Object getThrow() {
            log.info("Testing throw");
            throw new TestException("Testing throw");
        }
    }
    

    我的例外类是:

    package com.testing;
    
    public class TestException extends RuntimeException {
        public TestException(String message) {
            super(message);
        }
    }
    

    我已经创建了一个自定义记录来表示错误负载:

    package com.testing;
    
    public record CustomError (int code, String message, String description) { }
    

    我有一个ExceptionHandler实现:

    package com.testing;
    
    import io.micronaut.context.annotation.Requires;
    import io.micronaut.http.HttpRequest;
    import io.micronaut.http.HttpStatus;
    import io.micronaut.http.HttpResponse;
    import io.micronaut.http.annotation.Produces;
    import io.micronaut.http.server.exceptions.ExceptionHandler;
    import jakarta.inject.Singleton;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @Produces
    @Singleton
    @Requires(classes = {TestException.class, ExceptionHandler.class})
    public class TestExceptionHandler implements ExceptionHandler<TestException, HttpResponse<CustomError>> {
    
        private static final Logger log = LoggerFactory.getLogger(TestExceptionHandler.class);
    
        @Override
        public HttpResponse<CustomError> handle(HttpRequest request, TestException exception) {
            log.info("In handle method");
            var error = new CustomError(
                    HttpStatus.BAD_REQUEST.getCode(),
                    HttpStatus.BAD_REQUEST.name(),
                    "Bad Request found");
            return HttpResponse.badRequest().body(error);
        }
    }
    

    当我运行micronaut应用程序时,ExceptionHandler被正确调用,我看到的响应是:

    HTTP/1.1 400 Bad Request
    date: <the date>
    Content-Type: application/json
    content-length: 70
    connection: keep-alive
    
    {
      "code": 400,
      "message": "BAD_REQUEST",
      "description": "Bad Request found"
    }
    

    然而,当我尝试在JUnit测试中测试这一点时,客户端似乎抛出了一个异常:

    package com.testing;
    
    import io.micronaut.http.HttpStatus;
    import io.micronaut.http.client.HttpClient;
    import io.micronaut.http.client.annotation.Client;
    import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
    import jakarta.inject.Inject;
    import org.junit.jupiter.api.Test;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    import static org.junit.jupiter.api.Assertions.assertEquals;
    
    @MicronautTest
    public class TestControllerTest {
    
        private static final Logger log = LoggerFactory.getLogger(TestControllerTest.class);
    
        @Inject
        @Client("/test")
        HttpClient client;
    
        @Test
        public void testThrow() {
            log.info("Calling throw endpoint");
            assertDoesNotThrow(() -> {
                var response = client.toBlocking().exchange("/throw");
                log.info("Response: {}, {}", response, response.body());
                assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
            });
        }
    }
    
    

    控制台/堆栈竞赛开始于:

    16:14:51.684 [Test worker] INFO  i.m.context.env.DefaultEnvironment - Established active environments: [test]
    16:14:52.734 [Test worker] INFO  com.testing.TestControllerTest - Calling throw endpoint
    16:14:52.873 [default-nioEventLoopGroup-1-3] INFO  com.testing.TestController - Testing throw
    16:14:52.891 [default-nioEventLoopGroup-1-3] INFO  com.testing.TestExceptionHandler - In handle method
    
    Unexpected exception thrown: io.micronaut.http.client.exceptions.HttpClientResponseException: BAD_REQUEST
    org.opentest4j.AssertionFailedError: Unexpected exception thrown: io.micronaut.http.client.exceptions.HttpClientResponseException: BAD_REQUEST
        at app//org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
    

    我还需要做些什么来确保我的客户能够正确收到回复吗?

    1 回复  |  直到 3 年前
        1
  •  2
  •   toolkit    3 年前

    啊。我的错误。默认情况下,HttpClient表示它会为错误状态抛出一个异常:

    我可以使用以下方法覆盖此行为:

    # application.yml
    micronaut:
      http:
        client:
          exception-on-error-status: false
    
    @Test
    public void testThrow() {
        log.info("Calling throw endpoint");
        var response = client.toBlocking().exchange("/throw", String.class, String.class);
        assertEquals(HttpStatus.BAD_REQUEST, response.getStatus());
        log.info("Response: {}", response.body());
        assertEquals("{\"code\":400,\"message\":\"BAD_REQUEST\",\"description\":\"Bad Request found\"}", response.body());
    }
    

    或者,我可以允许抛出异常,并使用类似于以下的代码:

    @Test
    public void testThrow() {
        log.info("Calling throw endpoint");
        var error = assertThrows(HttpClientResponseException.class, () -> {
            client.toBlocking().exchange("/throw");
        });
        assertEquals(HttpStatus.BAD_REQUEST, error.getStatus());
        assertEquals("BAD_REQUEST", error.getMessage());
    }
    
    推荐文章