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 ()로 몇 가지 트릭을 시도했지만 아무것도 작동하지 않았습니다.
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(MockMvcResultHandlers.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'}"));
문자열 비교와 달리 "missing field xyz"또는 "message Expected 'ok'got 'nok'와 같은 메시지가 표시됩니다.
이 방법은 Spring 4.1에서 도입되었습니다.
이 답변을 읽으면 Spring 버전 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.")));
}
Taken from spring's tutorial
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
is available from import static org.hamcrest.Matchers.*;
jsonPath
is available from import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
and jsonPath
reference can be found here
String body = mockMvc.perform(bla... bla).andReturn().getResolvedException().getMessage()
This should give you the body of the response. "Username already taken" in your case.
here a more elegant way
mockMvc.perform(post("/retrieve?page=1&countReg=999999")
.header("Authorization", "Bearer " + validToken))
.andExpect(status().isOk())
.andExpect(content().string(containsString("regCount")));
Here is an example how to parse JSON response and even how to send a request with a bean in JSON form:
@Autowired
protected MockMvc mvc;
private static final ObjectMapper MAPPER = new ObjectMapper()
.configure(WRITE_DATES_AS_TIMESTAMPS, false)
.configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new JavaTimeModule());
public static String requestBody(Object request) {
try {
return MAPPER.writeValueAsString(request);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseResponse(MvcResult result, Class<T> responseClass) {
try {
String contentAsString = result.getResponse().getContentAsString();
return MAPPER.readValue(contentAsString, responseClass);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void testUpdate() {
Book book = new Book();
book.setTitle("1984");
book.setAuthor("Orwell");
MvcResult requestResult = mvc.perform(post("http://example.com/book/")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody(book)))
.andExpect(status().isOk())
.andReturn();
UpdateBookResponse updateBookResponse = parseResponse(requestResult, UpdateBookResponse.class);
assertEquals("1984", updateBookResponse.getTitle());
assertEquals("Orwell", updateBookResponse.getAuthor());
}
As you can see here the Book
is a request DTO and the UpdateBookResponse
is a response object parsed from JSON. You may want to change the Jakson's ObjectMapper
configuration.
참고URL : https://stackoverflow.com/questions/18336277/how-to-check-string-in-response-body-with-mockmvc
'Programing' 카테고리의 다른 글
Linux에서 세그멘테이션 오류로 코어 덤프를 생성하는 방법은 무엇입니까? (0) | 2020.05.09 |
---|---|
STL 맵에서 map :: insert를 사용하는 것이 []보다 낫습니까? (0) | 2020.05.09 |
루비 젬을 업그레이드하는 방법 (0) | 2020.05.08 |
ASP.Net MVC에서 Access-Control-Allow-Origin 설정-가장 간단한 방법 (0) | 2020.05.08 |
wget에 프록시를 설정하는 방법은 무엇입니까? (0) | 2020.05.08 |