일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 프로젝트
- java
- programmers
- 백트래킹
- 백준
- BFS
- 자바
- 그래프
- backtracking
- DFS
- 알고리즘
- 스프링
- back-end
- Spring
- 코틀린
- lambda
- DP
- TDD
- baekjoon
- 프로그래머스
- Brute-force
- OS
- 네트워크
- algorithm
- LEVEL2
- Java8
- 자료구조
- 운영체제
- kotlin
- 모던자바
- Today
- Total
요깨비's LAB
[Spring Boot, Back-End] 6. 가게 추가 본문
1. 가게 추가
이번에는 가게 추가 API를 만들어 보겠습니다.
- POST 메소드를 이용, /restaurants라는 리소스에 생성
- HTTP Status는 201(Created)을 리턴
- Header Location이라는 정보에 레스토랑에 대한 Resource를 담아서 보낼 거임
- Epmty{}
- HTTPie
2. UI Layer(Controller) Application Layer(Service)
#1 Controller 만들기
RestaurantControllerTest로 먼저 가서 생성 기능에 대한 테스트 코드를 먼저 작성하겠습니다.
@Test
public void create()throws Exception {
Restaurant restaurant = new Restaurant(1234L,"BeRyong","Seoul");
mvc.perform(post("/restaurants")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"Beryong\",\"address\":\"Busan\"}"))
.andExpect(status().isCreated())
.andExpect(header().string("location", "/restaurants/1234"))
.andExpect(content().string("{}"));
verify(restaurantService).addRestaurant(any()); // any()는 어떤 값을 넣어도 통과 시켜주는 임시 값
}
해당 테스트 코드를 통과시키기 위해 RestaurantController에 코드를 작성해 줍니다.
@PostMapping("/restaurants")
public ResponseEntity<?> create(@RequestBody Restaurant resource) throws URISyntaxException {
String name = resource.getName();
String address = resource.getAddress();
Restaurant restaurant = new Restaurant(1234L,name,address);
restaurantService.addRestaurant(restaurant);
URI location = new URI("/restaurants/1234");
return ResponseEntity.created(location).body("{}");
}
컨트롤러에 필요한 코드를 모두 작성하였습니다. 하지만 POST 요청을 통해 create를 수행하였지만 저장 기능이 없기 때문에
크게 의미 있어 보이지는 않습니다. 이제 Repository와 Service 관련 기능을 추가해줍니다.
#2 Service, Repository 만들기
Service를 위한 테스트 코드를 작성하겠습니다.
@Test
public void addRestaurant() {
setUp();
Restaurant restaurant = new Restaurant("BeRyong", "Busan");
Restaurant saved = new Restaurant(1234L, "BeRyong", "Busan");
given(restaurantRepository.save(null)).willReturn(saved);
Restaurant created = restaurantService.addRestaurant(restaurant);
assertThat(created.getId(), is(1234L));
}
테스트 코드를 통과시키기 위해 실제 RestaurantService 코드를 작성합니다.
public Restaurant addRestaurant(Restaurant restaurant) {
// TODO Auto-generated method stub
return restaurantRepository.save(restaurant);
}
하지만, RestaurantRepository에서 save코드를 구현하지 않았기 때문에 에러가 납니다. 이제 Repository를 구현합시다.
Repository를 위한 테스트 코드를 작성하겠습니다.
class RestaurantRepositoryImplTest {
@Test
public void save() {
RestaurantRepository restaurantRepository = new RestaurantRepositoryImpl();
int oldCount = restaurantRepository.findAll().size();
Restaurant restaurant = new Restaurant("BeRyong", "Seoul");
restaurantRepository.save(restaurant);
assertThat(restaurant.getId(), is(1234L));
int newCount = restaurantRepository.findAll().size();
assertThat(newCount - oldCount, is(1));
}
}
테스트 코드를 통과시키기 위한 실제 Reposiroty 구현 클래스를 작성합니다.
@Override
public Restaurant save(Restaurant restaurant) {
// TODO Auto-generated method stub
restaurant.setId(1234L);
restaurants.add(restaurant);
return restaurant;
}
POST MAN으로 확인하면 정상적으로 잘 작동하고 있습니다. 하지만 Repository에서 1234L로 아이디 값을 고정함으로
중복 아이디값이 생성되며 불안정합니다. 다음 강의에서 JPA를 사용하여 이를 수정하도록 하겠습니다.
항상 개발을 진행할 때 이렇게 먼저 테스트 코드를 작성하고 이것을 구현해 나가는 과정을 반복하면서 개발을 진행하면 더욱 안정적이고 실수 유발이 적어지는 코드를 짤 수 있습니다. 앞으로도 TDD 방식의 코드를 구현하는 습관을 들이도록 노력해야 겠습니다.
'웹 개발 > 스프링 부트 프로젝트(레스토랑 예약)' 카테고리의 다른 글
[Spring Boot, Back-End] 번외. Mock(가짜) 객체 (0) | 2020.01.16 |
---|---|
[Spring Boot, Back-End] 번외. 의존성 주입 (0) | 2020.01.07 |
[Spring Boot, Back-End] 5. 가게 상세 구현 (0) | 2020.01.07 |
[Spring Boot, Back-End] 4. 가게 목록 구현 (0) | 2019.12.30 |
[Spring Boot, Back-End] 3. Test Driven Development (0) | 2019.12.30 |