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

Far*_*mor 16 java testing junit spring spring-mvc

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

要突出显示意图,请提供代码段:

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

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

你会怎么解决这个问题?

Edd*_*e B 11

您可以获得对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))));
Run Code Online (Sandbox Code Playgroud)


Olu*_*oba 10

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

.andExpect(result -> assertTrue(result.getResolvedException() instanceof WhateverException))
Run Code Online (Sandbox Code Playgroud)

  • 更具体地说,为了在“@Controller”中存在异常的情况下使用“MvcResult.perform(...).andExpect()”,您需要将“@ExceptionHandler”注入到 Spring 测试上下文中,否则它会抛出异常在 `.perform()` 中,就在 `.andExpect()` 之前)) 谢谢伙伴! (2认同)

Bon*_*ond 8

您可以尝试以下操作-

  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);
    
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. @Rule在JUnit类中声明如下:

    @Rule
    public ExpectedException exception = ExpectedException.none();
    
    Run Code Online (Sandbox Code Playgroud)
  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());
    
    Run Code Online (Sandbox Code Playgroud)

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