728x90
스프링 기반 REST API 개발
2. 이벤트 생성 API 개발
포스팅 참조 정보
GitHub
공부한 내용은 GitHub에 공부용 Organizations에 정리 하고 있습니다
해당 포스팅에 대한 내용의 GitHub 주소
실습 내용이나 자세한 소스코드는 GitHub에 있습니다
포스팅 내용은 간략하게 추린 핵심 내용만 포스팅되어 있습니다
https://github.com/freespringlecture/spring-rest-api-study/tree/chap02-03_event_repo
해당 포스팅 참고 인프런 강의
https://www.inflearn.com/course/spring_rest-api/dashboard
실습 환경
- Java Version: Java 11
- SpringBoot Version: 2.1.2.RELEASE
3. Event 생성 API 구현: EventRepository 구현
스프링 데이터 JPA
JpaRepository 상속 받아 만들기
Enum을 JPA 맵핑시 주의할 것
@Enumerated(EnumType.STRING)
@MockBean
- Mockito를 사용해서 mock 객체를 만들고 빈으로 등록해 줌
- (주의) 기존 빈을 테스트용 빈이 대체 한다
테스트 할 것
- 입력값들을 전달하면 JSON 응답으로 201이 나오는지 확인
- Location 헤더에 생성된 이벤트를 조회할 수 있는 URI 담겨 있는지 확인
- id는 DB에 들어갈 때 자동생성된 값으로 나오는지 확인
EventRepository 구현
1. EventRepository 코드 작성
package me.freelife.rest.events;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EventRepository extends JpaRepository<Event, Integer> {
}
2. Event 도메인 클래스에 JPA 어노테이션 추가
...
import javax.persistence.*;
...
@Entity
public class Event {
@Id @GeneratedValue
private Integer id; // 추가 식별자
...
@Enumerated(EnumType.STRING)
private EventStatus eventStatus; // 이벤트 상태
}
3. EventController 에서 EventRepository 사용
package me.freelife.rest.events;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.net.URI;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_UTF8_VALUE)
public class EventController {
private final EventRepository eventRepository;
public EventController(EventRepository eventRepository) {
this.eventRepository = eventRepository;
}
@PostMapping
public ResponseEntity createEvent(@RequestBody Event event) {
Event newEvent = this.eventRepository.save(event);
//EventController의 id에 해당하는 링크를 만들고 링크를 URI로 변환
//API에 events에 어떤 특정한 ID 그 ID가 생성된 이벤트에 Location Header에 들어감
URI createdUri = linkTo(EventController.class).slash(newEvent.getId()).toUri();
event.setId(10);
// createdUri 헤더를 가지고 201응답을 만듬
return ResponseEntity.created(createdUri).body(event);
}
}
4. Event 생성 API 테스트 코드 EventRepository 사용하도록 수정
package me.freelife.rest.events;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTests {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
// 슬라이싱 테스트라 Repository가 빈으로 등록되지 않아 MockBean을 지정
// Mock 이라서 save 하는 값들이 전부 null
@MockBean
EventRepository eventRepository;
@Test
public void createEvent() throws Exception {
Event event = Event.builder()
.name("Spring")
.description("REST API Development with Spring")
.beginEnrollmentDateTime(LocalDateTime.of(2018, 11, 23, 14, 21))
.closeEnrollmentDateTime(LocalDateTime.of(2018, 11, 24, 14, 21))
.beginEventDateTime(LocalDateTime.of(2018, 11, 25, 14, 21))
.endEventDateTime(LocalDateTime.of(2018, 11, 26, 14, 21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 D2 스타텁 팩토리")
.build();
//이벤트 ID 10으로 임의 설정
event.setId(10);
//eventRepository에 save가 호출되면 event를 리턴하라
Mockito.when(eventRepository.save(event)).thenReturn(event);
mockMvc.perform(post("/api/events/")
.contentType(MediaType.APPLICATION_JSON_UTF8) //요청타입
.accept(MediaTypes.HAL_JSON) //받고싶은 타입
.content(objectMapper.writeValueAsString(event))) //event를 json을 String으로 맵핑
.andDo(print())
.andExpect(status().isCreated()) // 201 상태인지 확인
.andExpect(jsonPath("id").exists()) //ID가 있는지 확인
.andExpect(header().exists(HttpHeaders.LOCATION)) // HEADER에 Location 있는지 확인
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_JSON_UTF8_VALUE)); //Content-Type 값 확인
}
}
728x90
'개발강의정리 > Spring' 카테고리의 다른 글
[스프링 기반 REST API 개발] 2-5. Event 생성 API 구현: 입력값 이외에 에러 발생 (0) | 2019.12.28 |
---|---|
[스프링 기반 REST API 개발] 2-4. Event 생성 API 구현: 입력값 제한하기 (0) | 2019.12.28 |
[스프링 기반 REST API 개발] 2-2. Event 생성 API 구현: 201 응답 받기 (0) | 2019.12.28 |
[스프링 기반 REST API 개발] 2-1. Event 생성 API 구현: 테스트 만들자 (0) | 2019.12.28 |
[스프링 기반 REST API 개발] 1-6. 이벤트 비지니스 로직 (0) | 2019.12.27 |
댓글