반응형
Spring MockMVC 사용 시 JSON 응답에서 값을 추출하는 방법
POST 요구를 받아들이는 엔드포인트가 있다.JSON 응답에서 새로 생성된 엔티티의 ID를 얻고 싶습니다.
아래는 제가 시도하고 있는 코드의 일부입니다.
mockMvc.perform(post("/api/tracker/jobs/work")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(workRequest)))
.andExpect(status().isCreated());
이 ID를 얻으면 새로 생성된 엔티티에 대해 데이터베이스에 쿼리를 하고 다음과 같은 어설션을 수행합니다.
Work work = work service.findWorkById(id);
assertThat(work.getJobItem().getJobItemName()).isEqualTo(workRequest.getJobItem().getJobItemName());
assertThat(work.getJobItem().getQuantities()).hasSize(workRequest.getQuantities().size());
assertThat(work.getJobItem().getQuantityPools()).hasSize(workRequest.getQuantities().size());
간단하게 사용할 수 있습니다.JsonPath.read
결과 객체:
MvcResult result = mockMvc.perform(post("/api/tracker/jobs/work")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(workRequest)))
.andExpect(status().isCreated())
.andReturn();
String id = JsonPath.read(result.getResponse().getContentAsString(), "$.id")
Work work = workService.findWorkById(id);
...
Spring MockMVC 결과 핸들러를 사용하여 문제를 해결했습니다.JSON 문자열을 오브젝트로 변환하여 ID를 얻을 수 있도록 테스트 유틸리티를 만들었습니다.
변환 유틸리티:
public static <T> Object convertJSONStringToObject(String json, Class<T> objectClass) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
JavaTimeModule module = new JavaTimeModule();
mapper.registerModule(module);
return mapper.readValue(json, objectClass);
}
유닛 테스트:
@Test
@Transactional
public void createNewWorkWorkWhenCreatedJobItemAndQuantitiesPoolShouldBeCreated() throws Exception {
mockMvc.perform(post("/api/tracker/jobs/work")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(workRequest)))
.andExpect(status().isCreated())
.andDo(mvcResult -> {
String json = mvcResult.getResponse().getContentAsString();
workRequestResponse = (WorkRequestResponse) TestUtil.convertJSONStringToObject(json, WorkRequestResponse.class);
});
Work work = workService.findWorkById(workRequestResponse.getWorkId());
assertThat(work.getJobItem().getJobItemName()).isEqualTo(workRequest.getJobItem().getJobItemName());
assertThat(work.getJobItem().getQuantities()).hasSize(workRequest.getQuantities().size());
assertThat(work.getJobItem().getQuantityPools()).hasSize(workRequest.getQuantities().size());
}
JSON 응답에서 임의의 범용 값을 취득하는 방법 중 하나는 MockMVC 라이브러리에서 jsonPath() 매처를 활용하여 일치하는 모든 값을 캡처하는 커스텀매처와 결합하는 것입니다.
먼저 커스텀 매처:
import org.hamcrest.BaseMatcher;
/**
* Matcher which always returns true, and at the same time, captures the
* actual values passed in for matching. These can later be retrieved with a
* call to {@link #getLastMatched()} or {@link #getAllMatched()}.
*/
public static class CapturingMatcher extends BaseMatcher<Object> {
private List<Object> matchedList = new ArrayList<>();
@Override
public boolean matches(Object matched) {
matchedList.add(matched);
return true;
}
@Override
public void describeTo(Description description) {
description.appendText("any object");
}
/**
* The last value matched.
*/
public Object getLastMatched() {
return matchedList.get(matchedList.size() - 1);
}
/**
* All the values matched, in the order they were requested for
* matching.
*/
public List<Object> getAllMatched() {
return Collections.unmodifiableList(matchedList);
}
}
다음으로 커스텀 매처를 사용하여 값을 캡처하고 json Path() 매처를 사용하여 캡처해야 할 값을 지정합니다.
@Test
@WithMockUser(username = "reviewer", authorities = {ROLE_USER})
public void testGetRemediationAction() throws Exception {
CapturingMatcher capturingMatcher = new CapturingMatcher();
// First request a list of all the available actions
mvc.perform(get("/api/remediation/action").accept(VERSION_1_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.content[*].remediations[*].id", hasSize(12)))
.andExpect(jsonPath("$.content[*].remediations[*].id", capturingMatcher));
// Grab an ID from one of the available actions
Object idArray = capturingMatcher.getLastMatched();
assertThat(idArray).isInstanceOf(JSONArray.class);
JSONArray jsonIdArray = (JSONArray) idArray;
String randomId = (String) jsonIdArray.get(new Random().nextInt(12));
// Now retrieve the chosen action
mvc.perform(get("/api/remediation/action/" + randomId).accept(VERSION_1_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is(randomId)));
}
언급URL : https://stackoverflow.com/questions/47763332/how-to-extract-value-from-json-response-when-using-spring-mockmvc
반응형
'prosource' 카테고리의 다른 글
표준 json 모듈에서는 포맷이 플로팅됩니다. (0) | 2023.03.09 |
---|---|
Jackson이 Getter를 @JsonProperty로 덮어쓰지 않음 (0) | 2023.03.09 |
스프링 데이터 저장 시 'documentationPluginsBootstrapper'를 시작하지 못했습니다. (0) | 2023.03.09 |
angularjs, 이전 루트 경로 가져오기 (0) | 2023.03.09 |
사용자/게스트가 WooCommerce에서 특정 제품을 구입했는지 확인합니다. (0) | 2023.03.09 |