SpringBootプロジェクト(レストラン予約サイトの作成)-13の偽の対象を解読する
82913 ワード
ダミーオブジェクトとは、私たちが本来使用する行為と同じオブジェクトを指します.
#1レストランコントローラのテスト変更
次に、既存のテストコードを偽のオブジェクトで置き換えます.
これまで,以下のようにRestaurantServiceクラスを本格的に投入してテストを行ってきたならば,今から偽のオブジェクトを投入してテストを行う.
-既存-
/test/~/interfaces/RestaurantControllerTest.java
/test/~/interfaces/RestaurantControllerTest.java
このように偽のサービスを製造する理由は、コントローラをテストすることです.
私はサービスチームの実際の仕事状況に関心がありません.
これは、コントローラでサービスを使用すること自体に集中させるためです.
-変更後2-
/test/~/application/RestaurantServiceTest.java
#2レストランサービステスト変更
ここでは,サービステストで依存する実際のレジストリオブジェクトを各編成オブジェクトに変換する.
-既存-
/test/~/application/RestaurantServiceTest.java
/test/~/application/RestaurantServiceTest.java
#1レストランコントローラのテスト変更
次に、既存のテストコードを偽のオブジェクトで置き換えます.
これまで,以下のようにRestaurantServiceクラスを本格的に投入してテストを行ってきたならば,今から偽のオブジェクトを投入してテストを行う.
-既存-
/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\"")));
}
}
-変更後1-/test/~/interfaces/RestaurantControllerTest.java
package kr.co.fastcampus.eatgo.interfaces;
import kr.co.fastcampus.eatgo.application.RestaurantService;
import kr.co.fastcampus.eatgo.domain.*;
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.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.core.StringContains.containsString;
import static org.mockito.BDDMockito.given;
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생성, 리퀘스트 요청을 받는 테스트를 할때 사용
@MockBean // 스프링에서 제공하는, 테스트를위한 의존주입 가짜객체를 설정하는 어노테이션
private RestaurantService restaurantService;
@Test
public void list() throws Exception {
List<Restaurant> restaurants = new ArrayList<>();
restaurants.add(new Restaurant(1004L, "Bob zip", "Seoul")); // 우리가 테스트해서 나와야될값을 만들어준것.
given(restaurantService.getRestaurants()).willReturn(restaurants); // 우리는 여기 내부에서 가게목록들을 반환하는것을 알고있다. 우리는 getRestaurants가 가짜로 임의의 목록을 반환하게 만들것이다.
//given(restaurantService.getRestaurants()) 누군가가 이걸 실행하면 willReturn(restaurants) 이렇게 리턴할것이다라는 테스트이다.
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\"")));
}
}
リスト()テストに成功したことを確認できます.このように偽のサービスを製造する理由は、コントローラをテストすることです.
私はサービスチームの実際の仕事状況に関心がありません.
これは、コントローラでサービスを使用すること自体に集中させるためです.
-変更後2-
/test/~/application/RestaurantServiceTest.java
package kr.co.fastcampus.eatgo.interfaces;
import kr.co.fastcampus.eatgo.application.RestaurantService;
import kr.co.fastcampus.eatgo.domain.*;
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.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.core.StringContains.containsString;
import static org.mockito.BDDMockito.given;
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생성, 리퀘스트 요청을 받는 테스트를 할때 사용
@MockBean // 스프링에서 제공하는, 테스트를위한 의존주입 가짜객체를 설정하는 어노테이션
private RestaurantService restaurantService;
@Test
public void list() throws Exception {
List<Restaurant> restaurants = new ArrayList<>();
restaurants.add(new Restaurant(1004L, "Bob zip", "Seoul")); // 우리가 테스트해서 나와야될값을 만들어준것.
given(restaurantService.getRestaurants()).willReturn(restaurants); // 우리는 여기 내부에서 가게목록들을 반환하는것을 알고있다. 우리는 getRestaurants가 가짜로 임의의 목록을 반환하게 만들것이다.
//given(restaurantService.getRestaurants()) 누군가가 이걸 실행하면 willReturn(restaurants) 이렇게 리턴할것이다라는 테스트이다.
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 {
Restaurant restaurant1 = new Restaurant(1004L, "JOKER House", "Seoul");
restaurant1.addMenuItem(new MenuItem("Kimchi"));
Restaurant restaurant2 = new Restaurant(2020L, "Cyber Food", "Seoul");
restaurant2.addMenuItem(new MenuItem("Kimchi"));
given(restaurantService.getRestaurant(1004L)).willReturn(restaurant1);
given(restaurantService.getRestaurant(2020L)).willReturn(restaurant2);
mvc.perform(get("/restaurants/1004"))
.andExpect(status().isOk())
.andExpect(content().string(
containsString("\"id\":1004")
))
.andExpect(content().string(
containsString("\"name\":\"JOKER House\"")
))
.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\"")));
}
}
detail()もテストに合格したことをよく確認できます.#2レストランサービステスト変更
ここでは,サービステストで依存する実際のレジストリオブジェクトを各編成オブジェクトに変換する.
-既存-
/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"));
}
}
-変更後-/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 org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.given;
public class RestaurantServiceTest {
private RestaurantService restaurantService;
@Mock // 가짜객체 만드는 어노테이션
private RestaurantRepository restaurantRepository;
@Mock // 가짜객체 만드는 어노테이션
private MenuItemRepository menuItemRepository;
@Before // 모든 테스트가 실행되기전 이 어노테이션이 붙은 테스트가 먼저 실행되고 다음 테스트가 실행된다
public void setUp(){
MockitoAnnotations.initMocks(this); // 현재 @Mock 어노테이션이 붙어있는 객체를 초기화하는것
mockRestaurantRepository();
mockMenuItemRepository();
restaurantService = new RestaurantService(
restaurantRepository, menuItemRepository);
}
private void mockRestaurantRepository() {
List<Restaurant> restaurants = new ArrayList<>();
Restaurant restaurant = new Restaurant(1004L, "Bob zip", "Seoul");
restaurants.add(restaurant);
given(restaurantRepository.findAll()).willReturn(restaurants);
given(restaurantRepository.findById(1004L)).willReturn(restaurant);
}
private void mockMenuItemRepository() {
List<MenuItem> menuItems = new ArrayList<>();
menuItems.add(new MenuItem("Kimchi"));
given(menuItemRepository.findAllByRestaurantId(1004L)).willReturn(menuItems);
}
@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"));
}
}
テスト全体の成功を確認できます.Reference
この問題について(SpringBootプロジェクト(レストラン予約サイトの作成)-13の偽の対象を解読する), 我々は、より多くの情報をここで見つけました https://velog.io/@psj0810/스프링-부트-프로젝트레스토랑-예약-사이트-만들기-가짜객체-13강-해석テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol