繁体   English   中英

测试期间 spring webflux 中的全局异常处理

[英]Global exception handling in spring webflux during tests

我正在使用 spring webflux 开发服务。 我使用@ControllerAdvice实现了异常处理。 它工作得很好,但是当我运行集成测试时,似乎没有加载@ControllerAdvice注释的组件,导致以下响应:

{
   "timestamp":"2019-11-28T08:56:47.285+0000",
   "path":"/fooController/bar",
   "status":500,
   "error":"Internal Server Error",
   "message":"java.lang.IllegalStateException: Could not resolve parameter [1] in protected org.springframework.http.ResponseEntity<it.test.model.Response> it.test.exception.ExceptionHandlerController.handleServiceException(java.lang.Exception,org.springframework.web.context.request.WebRequest): No suitable resolver
}

这是我的控制器建议:

@ControllerAdvice
public class ExceptionHandlerController extends ResponseEntityExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(ExceptionHandlerController.class);

    @ExceptionHandler
    protected ResponseEntity<Response> handleServiceException(Exception ex, WebRequest request) {

        this.logger.error("Error occurred: \"{}\"", ex.getMessage());

        Response<Foo> response = new Response<>(new Foo(),
                "generic error",
                HttpStatus.INTERNAL_SERVER_ERROR);

        return new ResponseEntity<>(response, null, HttpStatus.OK);
    }
}

这是我的集成测试类

@ExtendWith(SpringExtension.class)
@WebFluxTest(MyController.class)
@ContextConfiguration(classes = {MyController.class, MyServiceImpl.class, ExceptionHandlerController.class })
public class MyControllerIT {

    @Autowired
    private WebTestClient webTestClient;

    @Test
    public void testShouldFail() throws IOException {

        return this.webTestClient.get()
            .uri(uri)
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            .expectStatus().isOk()
            .expectBody()
            .jsonPath("$.statusCode").isEqualTo(500);
    }
}

如果您阅读@WebFluxTest文档,它会指出:

可用于关注 Spring WebFlux 组件的 Spring WebFlux 测试的注释。

使用此注释将禁用完全自动配置,而是仅应用与 WebFlux 测试相关的配置(即 @Controller、@ControllerAdvice、@JsonComponent、Converter/GenericConverter 和 WebFluxConfigurer bean,但不应用 @Component、@Service 或 @Repository bean)。

通常@WebFluxTest 与@MockBean 或@Import 结合使用来创建@Controller bean 所需的任何协作者。

如果您希望加载完整的应用程序配置并使用 WebTestClient,则应考虑将 @SpringBootTest 与 @AutoConfigureWebTestClient 结合使用,而不是此注释。

这意味着

@ContextConfiguration(classes = {MyController.class, MyServiceImpl.class, ExceptionHandlerController.class })

不是你在这里使用的。 @WebFluxTest注释不加载@Component@Service@Repository

它主要仅用于测试 RestControllers 及其建议。

您的选择似乎是:

  • 加载 MyController.class,然后模拟该类具有的任何依赖项(MyServiceImpl.class)
  • 使用@SpringBootTest而不是结合@AutoConfigureWebTestClient加载完整的上下文

只是不在已经接受的答案之上,这是完全正确的。 @ContextConfiguration 的使用仅用于测试功能端点。 我想这可能是人们困惑的地方。

@WebFluxTest 在功能端点测试期间用于启动 Web 上下文和服务器。 但是由于我们不使用控制器,我们必须使用 @ContextConfiguration 将处理程序和 routerFunction bean 引入我们的 spring 上下文中。

在这种情况下,由于我们使用带注释的控制器,一个简单的 @WebFluxTest(Controller.class) 足以进行单元测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM