繁体   English   中英

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

[英]MockMVC how to test exception and response code in the same test case

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

为了突出意图,提供了一个代码片段:

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

当然,我写isInternalServerError还是isOk 无论是否在throw.except语句下方抛出异常,测试都将通过。

你打算如何解决这个问题?

您可以获得对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))));

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

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

您可以尝试以下操作 -

  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());

PS:我提供了一个通用的伪代码,您可以根据您的要求进行自定义。

我最近遇到了同样的错误,我没有使用 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

在您的控制器中:

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
    }

暂无
暂无

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

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