Как проверить строку в теле ответа с помощью mockMvc



у меня есть простой интеграционного тестирования



    @Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
.content("{"userName":"testUserDetails","firstName":"xxx","lastName":"xxx","password":"xxx"}"))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(?);
}


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



а в ответ я получаю:



MockHttpServletResponse:
Status = 400
Error message = null
Headers = {Content-Type=[application/json]}
Content type = application/json
Body = "Username already taken"
Forwarded URL = null
Redirected URL = null


пробовал некоторые трюки с content (), body () но ничего не получалось.

1563   8  

8 ответов:

можно назвать andReturn() и использовать возвращенный MvcResult объект, чтобы получить контент, как String. Смотрите ниже:

MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
            .content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
            .andDo(print())
            .andExpect(status().isBadRequest())
            .andReturn();

String content = result.getResponse().getContentAsString();
// do what you will

@Sotirios Delimanolis ответ сделать работу, однако я искал сравнения строк в этом утверждении mockMvc

вот это

.andExpect(content().string("\"Username already taken - please try with different username\""));

конечно, мое утверждение не выполнено:

java.lang.AssertionError: Response content expected:
<"Username already taken - please try with different username"> but was:<"Something gone wrong">

потому что:

  MockHttpServletResponse:
            Body = "Something gone wrong"

Так это доказательство того, что он работает!

Spring MockMvc теперь имеет прямую поддержку JSON. Поэтому вы просто говорите:

.andExpect(content().json("{'message':'ok'}"));

и в отличие от сравнения строк, он будет говорить что-то вроде "отсутствует поле xyz" или "сообщение ожидается 'ok' получил 'nok'.

этот метод был введен весной 4.1.

читая эти ответы, я вижу много, относящееся к весенней версии 4.x, я использую версию 3.2.0 по разным причинам. Так что такие вещи, как поддержка json прямо из content() не возможно.

я обнаружил, что с помощью MockMvcResultMatchers.jsonPath - Это очень легко и работает хорошо. Вот пример тестирования метода post.

бонус с этим решением заключается в том, что вы все еще сопоставляете атрибуты, не полагаясь на полное сравнение строк json.

(С помощью org.springframework.test.web.servlet.result.MockMvcResultMatchers)

String expectedData = "some value";
mockMvc.perform(post("/endPoint")
                .contentType(MediaType.APPLICATION_JSON)
                .content(mockRequestBodyAsString.getBytes()))
                .andExpect(status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));

тело запроса было просто строкой json, которую вы можете легко загрузить из реального файла данных JSON mock, если хотите, но я не включил это здесь, так как это было бы отклонено от вопроса.

фактическое возвращение json выглядело бы так:

{
    "data":"some value"
}

Весна безопасности @WithMockUser и hamcrest по containsString matcher делает для простого и элегантного решения:

@Test
@WithMockUser(roles = "USER")
public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception {
    mockMvc.perform(get("/index"))
            .andExpect(status().isOk())
            .andExpect(content().string(containsString("This content is only shown to users.")));
}

больше примеров на github

взята с весны учебник

    mockMvc.perform(get("/" + userName + "/bookmarks/"
            + this.bookmarkList.get(0).getId()))
            .andExpect(status().isOk())
            .andExpect(content().contentType(contentType))
            .andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue())))
            .andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName)))
            .andExpect(jsonPath("$.description", is("A description")));

is доступно import static org.hamcrest.Matchers.*;

jsonPath доступно import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

и jsonPath ссылка может быть найдена здесь

String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()

Это должно дать вам тело ответа. "Имя пользователя уже принято" в вашем случае.

для проверки конечного результата html вы можете получить весь вывод HTML по приведенному ниже коду и проверить сообщения в нем:

@Test
public void testHtmlOutput() throws Exception {
    String htmlBody = this.restTemplate.getForObject("/mypage, String.class);
    assertThat(htmlBody.contains("any message in html output"));
}

rest шаблон должен быть autowired:

@Autowired
private TestRestTemplate restTemplate;

и assertThat должны быть импортированы как статический метод:

import static org.assertj.core.api.Assertions.assertThat;

Comments

    Ничего не найдено.