REST를 위한 단위 테스트
RestController의 단위 테스트에는 com.jayway.jsonpath가 주로 사용된다.
https://goodteacher.tistory.com/495
테스트 해보기
전체 국가 조회
다음은 전체 국가 정보를 가져오는 get : /api/countries에 대한 단위 테스트 예이다. 테스트 항목은 주석으로 대체한다.
@Autowired
RestServiceController controller;
MockMvc mock;
@BeforeEach
public void setup() {
mock = MockMvcBuilders.standaloneSetup(controller).build();
}
@Test
public void selectAllTest() throws Exception {
mock.perform(get("/api/countries").param("per", "5").param("page", "1"))
.andExpect(status().isOk())
// 전달된 content type 검증
.andExpect(header().string("content-type", "application/json"))
// 배열의 개수 검증
.andExpect(jsonPath("$.data.length()", equalTo(5)))
// 데이터 검증
.andExpect(jsonPath("$.data[0].code", equalTo("ABW")))
.andDo(print());
}
특정 국가 정보 조회
다음은 특정 국가 정보를 조회하는 get :/api/countries/KOR에 대한 단위 테스트 예이다.
@Test
public void selectTest() throws Exception {
mock.perform(get("/api/countries/KOR"))
.andExpect(status().isOk())
// Country의 속성 개수
.andExpect(jsonPath("$.data.length()", equalTo(16)))
// Country 속성 값 검증
.andExpect(jsonPath("$.data.name", equalTo("South Korea")))
// 데이터 검증 - 배열의 개수
.andExpect(jsonPath("$.data.cities.length()", equalTo(70)))
// 데이터 검증 - 값
.andExpect(jsonPath("$.data.cities[0].district", equalTo("Seoul")))
.andDo(print());
}
국가 정보 추가
다음은 국가 추가를 위한 post :/api/countries에 대한 테스트 예이다. DML 테스트 이기 때문에 @Transactional이 사용되었고 Country 객체를 전달하기 위해 Jackson Databind를 이용해 JSON 형태의 문자열로 만들었다.
JSON 형태의 데이터를 전달하기 위해 contentType에 MediaType.APPLICATION_JSON으로 설정되었으며 content로 json 문자열을 넘겨준다.
@Test
@Transactional
public void insertTest() throws Exception {
Country country = new Country();
country.setCode("TTT");
country.setName("TestCountry");
country.setContinent("Asia");
country.setRegion("Eastern Asia");
country.setSurfaceArea(99434D);
country.setPopulation(46844000L);
country.setLocalName("Test Local Name");
country.setGovernmentForm("Republic");
country.setCode2("TT");
// Jackson Databind 사용(객체 JSON 문자열 변환)
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(country);
mock.perform(post("/api/countries").contentType(MediaType.APPLICATION_JSON).content(jsonStr))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success", is(true)))
.andExpect(jsonPath("$.data", is(1)))
.andDo(print());
}
국가 정보 수정
다음은 수정을 위해 put :/api/countries가 사용된 경우의 단위 테스트이다. 국가 정보 추가와 매우 유사하다.
@Test
@Transactional
public void updateTest() throws Exception {
Country country = new Country();
country.setCode("KOR");
country.setName("TestCountry");
country.setContinent("Asia");
country.setRegion("Eastern Asia");
country.setSurfaceArea(99434D);
country.setPopulation(46844000L);
country.setLocalName("Test Local Name");
country.setGovernmentForm("Republic");
country.setCode2("TT");
// Jackson Databind 사용
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(country);
mock.perform(put("/api/countries").contentType(MediaType.APPLICATION_JSON).content(jsonStr))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success", is(true)))
.andExpect(jsonPath("$.data", is(1)))
.andDo(print());
}
국가 정보 삭제
마지막으로 삭제를 위한 delete :/api/countries/ATA에 대한 테스트 예이다. countries 테이블은 city 테이블에서 참조하고 있기 때문에 하위 도시가 없는 ATA를 이용해서 테스트 하자.
@Test
@Transactional
public void deleteTest() throws Exception {
// 도시가 없는 국가만 삭제가 가능하다.
mock.perform(delete("/api/countries/ATA"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success", is(true)))
.andExpect(jsonPath("$.data", is(1)))
.andDo(print());
}