테스트 케이스 만들기
리스트를 조회하는 테스트케이스 생성
@Test
@DisplayName("30개의 이벤트를 10개씩 조회하기")
public void queryEvent() throws Exception {
IntStream.range(0, 30).forEach(i -> {
this.generateEvent(i);
});
this.mockMvc.perform(get("/api/events")
.param("page", "1")
.param("size", "10")
.param("sort", "name,DESC")
)
.andDo(print())
.andExpect(status().isOk());
}
Event 목록 Page 정보와 함께 받기
EventController에 queryEvents를 추가 Pageable을 사용시 페이지의 Requestparam의 page, sort, size 정보로 조회 가능
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
public class EventController {
@GetMapping
public ResponseEntity queryEvents(Pageable pageable) {
return ResponseEntity.ok(this.eventRepository.findAll(pageable));
}
}
Page관련 링크
PageResourcesAssembler를 이용해 page를 리소스로 변경할 수 있다. page와 관련된 링크 정보도 넘겨준다
@GetMapping
public ResponseEntity queryEvents(Pageable pageable, PagedResourcesAssembler<Event> assembler) {
Page<Event> page = this.eventRepository.findAll(pageable);
PagedModel<EntityModel<Event>> pagedModel = assembler.toModel(page);
return ResponseEntity.ok(pagedModel);
}

각각의 항목을 이벤트모델로 변경
toModel 메서드에 EventResource(e)를 추가
@GetMapping
public ResponseEntity queryEvents(Pageable pageable, PagedResourcesAssembler<Event> assembler) {
Page<Event> page = this.eventRepository.findAll(pageable);
PagedModel<EntityModel<Event>> pagedModel = assembler.toModel(page, e -> new EventResource(e));
return ResponseEntity.ok(pagedModel);
}

Profile 추가하기
pageModel에 add로 Link를 추가한다
@GetMapping
public ResponseEntity queryEvents(Pageable pageable, PagedResourcesAssembler<Event> assembler) {
Page<Event> page = this.eventRepository.findAll(pageable);
PagedModel<EntityModel<Event>> pagedModel = assembler.toModel(page, e -> new EventResource(e));
pagedModel.add(Link.of("/docs/index.html#resources-events-list").withRel("profile"));
return ResponseEntity.ok(pagedModel);
}
Test
_links.self가 있는지 확인
@Test
@DisplayName("30개의 이벤트를 10개씩 조회하기")
public void queryEvent() throws Exception {
IntStream.range(0, 30).forEach(i -> {
this.generateEvent(i);
});
this.mockMvc.perform(get("/api/events")
.param("page", "1")
.param("size", "10")
.param("sort", "name,DESC")
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("page").exists())
.andExpect(jsonPath("_embedded.eventList[0]._links.self").exists())
.andExpect(jsonPath("_links.self").exists())
.andDo(document("query-events"))
.andExpect(jsonPath("_embedded.eventList[0]._links.self").exists())
;
}
Event 하나를 id로 조회하는 API 테스트 구현
get에 {id}에 event.getId를 넣어줌
@Test
@DisplayName("기존의 이벤트를 하나 조회하기")
public void getEvent() throws Exception {
//Given
Event event = this.generateEvent(100);
// When & Than
this.mockMvc.perform(get("/api/events/{id}", event.getId()))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("name").exists())
.andExpect(jsonPath("id").exists())
.andExpect(jsonPath("_links.self").exists())
.andExpect(jsonPath("_links.profile").exists())
.andDo(document("get-an-event"));
}
Event 조회 실패 테스트
조회에 실패 했을때 404가 뜨는지 확인
@Test
@DisplayName("없는 이벤트 조회했을 떄 404 응답받기")
public void getEvent_fail() throws Exception {
// When & Than
this.mockMvc.perform(get("/api/events/1234"))
.andExpect(status().isNotFound())
.andDo(print())
실패시 404 반환
OptinalEvent가 비어 있을 시 notFound를 반환
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)
public class EventController {
//...
@GetMapping("/{id}")
public ResponseEntity getEvent(@PathVariable Long id) {
Optional<Event> optionalEvent = this.eventRepository.findById(id);
if (optionalEvent.isEmpty())
return ResponseEntity.notFound().build();
Event event = optionalEvent.get();
EventResource eventResource = new EventResource(event);
return ResponseEntity.ok(eventResource);
}
}
Profile 링크 생성
eventResource.add에 Link를 이용해 profile링크를 생성
@GetMapping("/{id}")
public ResponseEntity getEvent(@PathVariable Long id) {
Optional<Event> optionalEvent = this.eventRepository.findById(id);
if (optionalEvent.isEmpty())
return ResponseEntity.notFound().build();
Event event = optionalEvent.get();
EventResource eventResource = new EventResource(event);
**eventResource.add(Link.of("/docs/index.html#resources-events-get").withRel("profile"));**
return ResponseEntity.ok(eventResource);
}
이벤트를 정상적으로 수정하기
eventDto의 이름을 수정해 이를 이벤트 객체에 수정하고 결과 확인
@Test
@DisplayName("이벤트를 정상적으로 수정하기")
public void updateEvent() throws Exception {
// Given
Event event = this.generateEvent(200);
EventDto eventDto = this.modelMapper.map(event, EventDto.class);
String eventName = "Updated Event";
eventDto.setName(eventName);
// When & Then
this.mockMvc.perform(put("/api/events/{id}", event.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(this.objectMapper.writeValueAsString(eventDto))
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("name").value(eventDto.getName()))
.andExpect(jsonPath("_links.self").exists());
}
입력 값이 없는 경우에 이벤트 수정 실패하는 테스트
@Test
@DisplayName("입력값이 없는 경우에 이벤트 수정 실패")
public void updateEvent400() throws Exception {
// Given
Event event = this.generateEvent(200);
EventDto eventDto = new EventDto();
// When & Then
this.mockMvc.perform(put("/api/events/{id}", event.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(this.objectMapper.writeValueAsString(eventDto))
)
.andDo(print())
.andExpect(status().isBadRequest());
}