요깨비's LAB

[Spring Boot, Back-End] 6. 가게 추가 본문

웹 개발/스프링 부트 프로젝트(레스토랑 예약)

[Spring Boot, Back-End] 6. 가게 추가

요깨비 2020. 1. 16. 21:26

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 방식의 코드를 구현하는 습관을 들이도록 노력해야 겠습니다.

Comments