[사이드프로젝트] 그저 그런 REST API로 괜찮은가? - 진정한 REST API 구현해보기 - Event 수정 로직 구현하기

Evnt Update Test 구현하기


이번에는 Event API 중 마지막 기능인 이벤트 수정 기능을 구현할 것이다.

고려해야할 사항은 다음과 같다.

  • 수정한 경우, 수정된 event 값을 넘겨줘야하며 HATEOAS를 만족해야한다.
  • 존재하지 않는 id 값으로 들어온 경우, Notfound 에러 메시지를 반환한다.
  • body에 잘못된 값이 넘어간 경우(ex Empty), BadRequest 메시지를 반환한다.
    @Test
    public void update_event_success() throws Exception {
        //Given
        Event event = createEvent(11123);
        this.eventRepository.save(event);
        String newDescription = "new description";

        EventDto eventDto = EventDto.builder()
                .name(event.getName())
                .description(newDescription)
                .build();

        //When
        //Then
        mockMvc.perform(put("/api/events/{id}", event.getId())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(eventDto)))
                .andDo(print())
                .andExpect(jsonPath("event.name").value(event.getName()))
                .andExpect(jsonPath("event.description").value(newDescription))
                .andExpect(jsonPath("_links").exists());
    }

    @Test
    public void update_event_bad_requset_empty_input() throws Exception {
        //Given
        Event event = createEvent(11223);
        this.eventRepository.save(event);

        EventDto eventDto = EventDto.builder()
                .build();

        //When
        //Then
        mockMvc.perform(put("/api/events/{id}", event.getId())
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(eventDto)))
                .andDo(print())
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("timestamp").exists())
                .andExpect(jsonPath("status").exists())
                .andExpect(jsonPath("error").exists())
                .andExpect(jsonPath("message").exists());
    }

    @Test
    public void update_event_not_found_wrong_id() throws Exception {
        //Given
        Integer wrongId = 10010;
        EventDto eventDto = createEventDto();

        //When
        //Then
        mockMvc.perform(put("/api/events/{id}", wrongId)
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(eventDto)))
                .andDo(print())
                .andExpect(status().isNotFound())
                .andExpect(jsonPath("timestamp").exists())
                .andExpect(jsonPath("status").exists())
                .andExpect(jsonPath("error").exists())
                .andExpect(jsonPath("message").exists());
    }

Service 구현


여기서 중요한 점은 존재하지 않는 아이디로 들어온 경우, NotFound를 반환하는 로직이 이미 read() 메소드에 구현되어 있다. 이를 재활용하면 코드가 더 간결해진다.

    public Event update(Integer id, EventDto eventDto){
        Event event = this.read(id);
        event.setName(eventDto.getName());
        event.setDescription(eventDto.getDescription());
        return this.eventRepository.save(event);
    }

Controller 구현


여기서도 마찬가지로 @Valid 어노테이션을 통해 유효하지 않은 EventDto를 예외처리 해준다.

    @PutMapping("/{id}")
    public ResponseEntity update(@RequestBody @Valid EventDto eventDto, @PathVariable Integer id){
        Event event = this.eventService.update(id, eventDto);
        EventResource eventResource = new EventResource(event);
        addLinks(eventResource);
        return ResponseEntity.ok(eventResource);
    }

테스트 결과


좋은 웹페이지 즐겨찾기