测试期间Spring Webflux中的全局异常处理

时间:2019-11-28 09:26:12

标签: java spring spring-boot spring-cloud spring-webflux

我正在使用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);
    }
}

2 个答案:

答案 0 :(得分:1)

如果您为@WebFluxTest读过documentation,则说明:

  

可用于重点关注的Spring WebFlux测试的注释   在Spring WebFlux组件上。

     

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

     

@WebFluxTest通常与@MockBean或   @导入创建@Controller所需的任何协作者   豆。

     

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

这意味着

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

不是不是您在此处使用的内容。 @WebFluxTest注释不会加载@Component@Service@Repository

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

您似乎有以下选择:

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

答案 1 :(得分:1)

仅在已被接受的答案之上没有,这是完全正确的。 仅在测试功能端点时才需要使用@ContextConfiguration。我认为这可能会让人们感到困惑。

在功能端点测试期间,使用

@WebFluxTest启动Web上下文和服务器。 但是由于我们不使用控制器,所以我们必须使用@ContextConfiguration将处理程序和routerFunction Bean带入我们的Spring上下文。

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