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


Answers

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

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

Question

간단한 통합 테스트가 있습니다.

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




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

MockMvcResultMatchers.jsonPath 를 사용 MockMvcResultMatchers.jsonPath 것이 정말 쉽고 MockMvcResultMatchers.jsonPath 가 있다는 것을 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"
}



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"));
}

나머지 템플릿은 autowired해야합니다 :

@Autowired
private TestRestTemplate restTemplate;

assertThat은 정적 메서드로 가져와야합니다.

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