MockMVC如何在同一测试用例中测试异常和响应代码

时间:2013-05-17 09:33:01

标签: java spring testing spring-mvc junit

我想声明引发异常并且服务器返回500内部服务器错误。

要突出显示提示代码段的意图:

thrown.expect(NestedServletException.class);
this.mockMvc.perform(post("/account")
            .contentType(MediaType.APPLICATION_JSON)
            .content(requestString))
            .andExpect(status().isInternalServerError());

当然,如果我写isInternalServerErrorisOk,这无关紧要。 无论是否在throw.except语句下面抛出异常,测试都将通过。

你将如何解决这个问题?

5 个答案:

答案 0 :(得分:5)

如果您具有异常处理程序,并且想要测试特定的异常,则还可以断言该实例在已解决的异常中有效。

.andExpect(result -> assertTrue(result.getResolvedException() instanceof WhateverException))

答案 1 :(得分:4)

您可以尝试以下内容 -

  1. 创建自定义匹配器

    public class CustomExceptionMatcher extends
    TypeSafeMatcher<CustomException> {
    
    private String actual;
    private String expected;
    
    private CustomExceptionMatcher (String expected) {
        this.expected = expected;
    }
    
    public static CustomExceptionMatcher assertSomeThing(String expected) {
        return new CustomExceptionMatcher (expected);
    }
    
    @Override
    protected boolean matchesSafely(CustomException exception) {
        actual = exception.getSomeInformation();
        return actual.equals(expected);
    }
    
    @Override
    public void describeTo(Description desc) {
        desc.appendText("Actual =").appendValue(actual)
            .appendText(" Expected =").appendValue(
                    expected);
    
    }
    }
    
  2. 在JUnit类中声明@Rule,如下所示 -

    @Rule
    public ExpectedException exception = ExpectedException.none();
    
  3. 在测试用例中使用自定义匹配器为 -

    exception.expect(CustomException.class);
    exception.expect(CustomException
            .assertSomeThing("Some assertion text"));
    this.mockMvc.perform(post("/account")
        .contentType(MediaType.APPLICATION_JSON)
        .content(requestString))
        .andExpect(status().isInternalServerError());
    
  4. P.S。:我提供了一个通用的伪代码,您可以根据自己的要求进行自定义。

答案 2 :(得分:0)

在您的控制器中:

throw new Exception("Athlete with same username already exists...");

在你的测试中:

    try {
        mockMvc.perform(post("/api/athlete").contentType(contentType).
                content(TestUtil.convertObjectToJsonBytes(wAthleteFTP)))
                .andExpect(status().isInternalServerError())
                .andExpect(content().string("Athlete with same username already exists..."))
                .andDo(print());
    } catch (Exception e){
        //sink it
    }

答案 3 :(得分:0)

您可以获得对MvcResult和可能解决的异常的引用,并使用一般的junit断言进行检查...

          MvcResult result = this.mvc.perform(
                post("/api/some/endpoint")
                        .contentType(TestUtil.APPLICATION_JSON_UTF8)
                        .content(TestUtil.convertObjectToJsonBytes(someObject)))
                .andDo(print())
                .andExpect(status().is4xxClientError())
                .andReturn();

        Optional<SomeException> someException = Optional.ofNullable((SomeException) result.getResolvedException());

        someException.ifPresent( (se) -> assertThat(se, is(notNullValue())));
        someException.ifPresent( (se) -> assertThat(se, is(instanceOf(SomeException.class))));

答案 4 :(得分:0)

我最近遇到了相同的错误,并且没有使用MockMVC,而是创建了如下的集成测试:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = { MyTestConfiguration.class })
public class MyTest {
    
    @Autowired
    private TestRestTemplate testRestTemplate;
    
    @Test
    public void myTest() throws Exception {
        
        ResponseEntity<String> response = testRestTemplate.getForEntity("/test", String.class);
        
        assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode(), "unexpected status code");
        
    }   
}

@Configuration
@EnableAutoConfiguration(exclude = NotDesiredConfiguration.class)
public class MyTestConfiguration {
    
    @RestController
    public class TestController {
        
        @GetMapping("/test")
        public ResponseEntity<String> get() throws Exception{
            throw new Exception("not nice");
        }           
    }   
}

此帖子非常有帮助:https://github.com/spring-projects/spring-boot/issues/7321