복붙노트

[SPRING] mockMvc를 사용하여 응답 본문에서 문자열을 확인하는 방법

SPRING

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 ()로 몇 가지 트릭을 시도했지만 아무 것도 작동하지 않았습니다.

해결법

  1. ==============================

    1.andReturn ()을 호출하고 반환 된 MvcResult 객체를 사용하여 내용을 문자열로 가져올 수 있습니다. 아래 참조 :

    andReturn ()을 호출하고 반환 된 MvcResult 객체를 사용하여 내용을 문자열로 가져올 수 있습니다. 아래 참조 :

    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
    
  2. ==============================

    2.@Sotirios Delimanolis 대답은 일을하지만 나는이 mockMvc 어설 션 내에서 문자열 비교를 찾고있었습니다.

    @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"
    

    이것이 작동한다는 증거입니다!

  3. ==============================

    3.Spring MockMvc는 이제 JSON을 직접 지원합니다. 그래서 당신은 단지 말합니다 :

    Spring MockMvc는 이제 JSON을 직접 지원합니다. 그래서 당신은 단지 말합니다 :

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

    문자열 비교와 달리 "missing field xyz"또는 "message ok '가'nok '가 될 것입니다.

    이 메소드는 Spring 4.1에서 소개되었다.

  4. ==============================

    4.이 답변을 읽으면 스프링 버전 4.x와 관련하여 많은 것을 볼 수 있습니다. 여러 가지 이유로 버전 3.2.0을 사용하고 있습니다. 콘텐츠 ()에서 바로 json을 지원하는 것과 같은 일은 불가능합니다.

    이 답변을 읽으면 스프링 버전 4.x와 관련하여 많은 것을 볼 수 있습니다. 여러 가지 이유로 버전 3.2.0을 사용하고 있습니다. 콘텐츠 ()에서 바로 json을 지원하는 것과 같은 일은 불가능합니다.

    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"
    }
    
  5. ==============================

    5.스프링 보안 @WithMockUser와 hamcrest containsString 매처는 간단하고 우아한 해결책을 만든다 :

    스프링 보안 @WithMockUser와 hamcrest containsString 매처는 간단하고 우아한 해결책을 만든다 :

    @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에 대한 추가 예제

  6. ==============================

    6.봄의 튜토리얼에서 가져온 것

    봄의 튜토리얼에서 가져온 것

        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 org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath에서 가져올 수 있습니다.

    jsonPath 참조는 여기에서 찾을 수 있습니다.

  7. ==============================

    7.

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

    이것은 응답의 본문을 제공해야합니다. 자신의 케이스에서 "이미 사용 된 사용자 이름".

  8. from https://stackoverflow.com/questions/18336277/how-to-check-string-in-response-body-with-mockmvc by cc-by-sa and MIT license