Как проверить строку в теле ответа с помощью 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 () но ничего не получалось.
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 поcontainsStringmatcher делает для простого и элегантного решения:@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."))); }
взята с весны учебник
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