【问题标题】:Why doesnt Springboot Mockmvc.perform handle exceptions on controller?为什么 Spring Boot Mockmvc.perform 不处理控制器中的异常?
【发布时间】:2020-07-15 17:45:38
【问题描述】:

我编写了以下代码,mockmvc.perform 不会捕获异常,而是返回错误堆栈。我使用调试器确认控制器抛出了正确的错误。我是 SpringBoot 新手,不明白为什么测试控制器没有处理异常。以下是我的测试控制器,它对外部服务进行了三个 Api 调用。控制器返回异常,但 Mockmvc.perform 无法断言它。

    @ExtendWith(SpringExtension.class)
    @SpringBootTest(classes = { Application.class, ApplicationTest.class })
    @AutoConfigureMockMvc
    @ContextConfiguration(initializers = {WireMockInitializer.class})
    public class myControllerIntegrationTest {
        @Autowired
        private MockMvc mockMvc;
        @Autowired private WireMockServer wireMockServer;
        @Autowired
        private myController myController;
    
        @Before
        public void setup() {
           this.mockMvc = MockMvcBuilders.standaloneSetup(myController)
            .build();
        }
        @Test
        @DisplayName("Should Return Execution Error")
        public void shouldReturnExecutionErrorOnService() throws Exception {
          // Making Three Api calls the controller internally invokes them
          configureStubA(HttpStatus.INTERNAL_SERVER_ERROR, args, "invalidResponse.json");
          configureStubB(HttpStatus.INTERNAL_SERVER_ERROR, args, args2, args3, 
            "invalidResponse.json");
          configureStubC(HttpStatus.INTERNAL_SERVER_ERROR, args, "invalidResponse.json");
            mockMvc
              .perform(
                 get("/something")
                    .param("a", a)
                    .param("b", b)
                    .param("c", c)
                    .param("d", d)
                    .param("e", e.toArray(new String[] {})))
            .andDo(print())
            .andExpect(status().is5xxServerError())
            .andExpect(result -> assertTrue(result.getResolvedException() instanceof 
               IllegalStateException));
         }}

【问题讨论】:

    标签: spring-boot mocking mockito integration


    【解决方案1】:

    API 本身永远不会返回异常。 可以把它想象成当你调用一个 API 时,你总会得到响应,对吧?

    Spring Controller 处理 Exception 的方式是它有一个默认的异常处理程序,它将从你的 Controller 抛出的任何异常转换为一个 Response 对象,然后将其转换为 json/xml 并返回给你。

    【讨论】:

    • 感谢您的回答。我明白这就是 mockmvc.perform 的工作原理,但我没有得到上述响应,而是我的测试用例失败了,我取回了堆栈跟踪
    【解决方案2】:

    获得预期结果的一种方法是声明您自己的异常,使用@ResponseStatus 对其进行注释,然后将您希望将异常映射到的 http 状态代码传递给它。

    例如(我在下面的sn-ps中使用的是Kotlin)你可以通过这种方式声明http状态码500和你的异常之间的映射:

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    class MyException(message: String) : RuntimeException(message)
    

    然后在您的测试中,您将能够像在 sn-p 中所做的那样断言内部错误。

    mockMvc.perform(get("/foo")).andExpect(status().isInternalServerError)
    

    更多详情请查看herehere

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 2019-10-09
      • 2022-11-29
      • 2023-03-28
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      相关资源
      最近更新 更多