簡體   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