MockMVC, как проверить код исключения и ответа в том же тестовом примере

Я хочу утверждать, что возникает исключение и сервер возвращает ошибку внутреннего сервера 500.

Чтобы выделить намерение, предоставляется фрагмент кода:

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

Конечно, неважно, напишу ли я isInternalServerError или isOk. Тест пройдет независимо от того, будет ли исключение выведено ниже оператора throw.except.

Как вы собираетесь это решить?

Ответ 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);
    
    }
    }
    
  • Объявите @Rule в классе JUnit, как показано ниже -

    @Rule
    public ExpectedException exception = ExpectedException.none();
    
  • Использовать пользовательский соединитель в тестовом примере как -

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

P.S.: Я предоставил общий псевдо-код, который вы можете настроить в соответствии с вашим требованием.

Ответ 2

В вашем контроллере:

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

Вы можете получить ссылку на 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))));