스프링 부트 프로젝트(레스토랑 예약 사이트 만들기)-레이어 분리-2 12강 해석

Psj·2021년 12월 21일
0

#1

기존의 레파지토리들은 일종의 컬렉션과 같은 역할을 했다고한다면 우리는 지금까지했던 복잡한 과정들이 한꺼번에 일어나는 새로운 객체를 Service로 만들것이다.
그리고 컨트롤러에서 기존의 레파지토리들은 삭제할것이다.

/test/~/interfaces/RestaurantControllerTest.java

package kr.co.fastcampus.eatgo.interfaces;

import kr.co.fastcampus.eatgo.application.RestaurantService;
import kr.co.fastcampus.eatgo.domain.MenuItemRepository;
import kr.co.fastcampus.eatgo.domain.MenuItemRepositoryImpl;
import kr.co.fastcampus.eatgo.domain.RestaurantRepository;
import kr.co.fastcampus.eatgo.domain.RestaurantRepositoryImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.hamcrest.core.StringContains.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class) // api 요청처리 테스트를 해주기위한 스프링자체의 어노테이션
@WebMvcTest(RestaurantController.class) // 특정 컨트롤러를 테스트해준다는것을 명시하는 어노테이션
public class RestaurantControllerTest {

    @Autowired
    private MockMvc mvc; // MockMvc생성

    @SpyBean(RestaurantService.class) // service 테스트
    private RestaurantService restaurantService;

    @SpyBean(RestaurantRepositoryImpl.class) // 일단은 테스트에서는 남겨놓는다
    private RestaurantRepository restaurantRepository;

    @SpyBean(MenuItemRepositoryImpl.class) // 일단은 테스트에서는 남겨놓는다
    private MenuItemRepository menuItemRepository;

    @Test
    public void list() throws Exception {
        mvc.perform(get("/restaurants"))
        .andExpect(status().isOk())
        .andExpect(content().string(containsString("\"id\":1004")))
        .andExpect(content().string(containsString("\"name\":\"Bob zip\"")));

    }

    @Test
    public void detail() throws Exception {
        mvc.perform(get("/restaurants/1004"))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("\"id\":1004")))
                .andExpect(content().string(containsString("\"name\":\"Bob zip\"")))
                .andExpect(content().string( 
                        containsString(("Kimchi")) // 메뉴추가 테스트
                ));

        mvc.perform(get("/restaurants/2020"))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("\"id\":2020")))
                .andExpect(content().string(containsString("\"name\":\"Cyber Food\"")));
    }
}

/main/~/interfaces/RestaurantController.java

package kr.co.fastcampus.eatgo.interfaces;

import kr.co.fastcampus.eatgo.application.RestaurantService;
import kr.co.fastcampus.eatgo.domain.MenuItem;
import kr.co.fastcampus.eatgo.domain.MenuItemRepository;
import kr.co.fastcampus.eatgo.domain.Restaurant;
import kr.co.fastcampus.eatgo.domain.RestaurantRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class RestaurantController {

    @Autowired
    private RestaurantService restarantService; // 기존의 레파지토리를 삭제하고 RestaurantService로 기능을 통합하였다.

    @GetMapping("/restaurants") // 가게목록 반환 api
    public List<Restaurant> list(){

        List<Restaurant> restaurants = restarantService.getRestaurants();

        return restaurants;
    }

    @GetMapping("/restaurants/{id}") // 특정 가게상세 반환 api
    public Restaurant detail(@PathVariable("id") Long id){

        Restaurant restaurant = restarantService.getRestaurant(id); // 가게의 기본정보 + 메뉴 정보를 반환하는 기능능

        return restaurant;
    }

}

/test/~/application/RestaurantServiceTest.java 생성

package kr.co.fastcampus.eatgo.application;

import kr.co.fastcampus.eatgo.domain.*;
import org.junit.Before;
import org.junit.Test;

import java.util.List;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;

public class RestaurantServiceTest {

    private RestaurantService restaurantService;
    private RestaurantRepository restaurantRepository;
    private MenuItemRepository menuItemRepository;

    @Before // 모든 테스트가 실행되기전 이 어노테이션이 붙은 테스트가 먼저 실행되고 다음 테스트가 실행된다
    public void setUp(){
        restaurantRepository = new RestaurantRepositoryImpl();
        menuItemRepository = new MenuItemRepositoryImpl();

        restaurantService = new RestaurantService(restaurantRepository, menuItemRepository);
    }

    @Test
    public void getRestaurants(){
        List<Restaurant> restaurants = restaurantService.getRestaurants();

        Restaurant restaurant = restaurants.get(0);
        assertThat(restaurant.getId(), is(1004L));

    }

    @Test
    public void getRestaurant(){
        Restaurant restaurant = restaurantService.getRestaurant(1004L);

        assertThat(restaurant.getId(), is(1004L));

        MenuItem menuItem = restaurant.getMenuItems().get(0);

        assertThat(menuItem.getName(), is("Kimchi"));

    }

}

/main/~/application/RestaurantService.java 생성

package kr.co.fastcampus.eatgo.application;

import kr.co.fastcampus.eatgo.domain.MenuItem;
import kr.co.fastcampus.eatgo.domain.MenuItemRepository;
import kr.co.fastcampus.eatgo.domain.Restaurant;
import kr.co.fastcampus.eatgo.domain.RestaurantRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service // 서비스를 지정하는 어노테이션
public class RestaurantService {

    @Autowired
    RestaurantRepository restaurantRepository;

    @Autowired
    MenuItemRepository menuItemsRepository;

    public RestaurantService(RestaurantRepository restaurantRepository,
                             MenuItemRepository menuItemRepository) {
        this.restaurantRepository = restaurantRepository;
        this.menuItemsRepository = menuItemRepository;
    }

    public List<Restaurant> getRestaurants() { //가게목록 반환

        List<Restaurant> restaurants = restaurantRepository.findAll();

        return restaurants;
    }

    public Restaurant getRestaurant(Long id){ // 특정 가게 반환
        Restaurant restaurant = restaurantRepository.findById(id); // 요청되는 id에 따른 특정 가게 반환

        List<MenuItem> menuItems = menuItemsRepository.findAllByRestaurantId(id); // 요청되는 id에 따른 가게 메뉴목록 반환
        restaurant.setMenuItems(menuItems);  // 특정가게의 메뉴목록들 추가

        return restaurant;
    }
}

profile
Software Developer

0개의 댓글