티스토리 뷰

Spring

Spring5 , Mockito 관련 간단 정리.

0307kjb 2022. 1. 13. 21:15

REST API :
REpresentaitional state Transter ( 표현 상태 - Resource(URL, URI) >CRUD )
결과를 받거나 넘길 때 JSON 데이터로 공유한다.

 

이 개념을 알아두고 시작한다.

 

@RestController
public class RestaurantController {

    @Autowired
    private RestaurantService restaurantService;

    @GetMapping("/restaurants")
    public List<Restaurant> getRestaurants(){
        return restaurantService.getRestaurants();
    }

    @GetMapping("/restaurants/{id}")
    public Restaurant getRestaurant(@PathVariable("id") long id){
        return restaurantService.getRestaurant(id);
    }
}


이것을 테스트하는,

@ExtendWith(SpringExtension.class)
@WebMvcTest(RestaurantController.class)
class RestaurantControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private RestaurantService restaurantService;

    /*
    @SpyBean(구현체.class) controller에 의존성주입. ( 객체를 다양하게 변형 가능 )
    컨트롤러가 아니라면 즉 서비스는 @Before를 가진 메서드를 통해 의존성 주입을 직접해줘야한다.(Service)
    * */

    @BeforeEach
    public void setUp(){
        List<Restaurant> restaurantList = new ArrayList<>();
        Restaurant restaurant = new Restaurant(1004L, "JOKER HOUSE", "Seoul");
        restaurantList.add(restaurant);
        restaurantList.add(new Restaurant(2020L, "NUKER HOUSE", "Seoul"));
        given(restaurantService.getRestaurant(1004L)).willReturn(restaurant);
        given(restaurantService.getRestaurants()).willReturn(restaurantList);
    }

    @Test
    public void getRestaurants() throws Exception {

         mvc.perform(get("/restaurants")).andExpect(status().isOk())
                .andExpect(content().string(containsString("\"id\":1004")));

    }

    @Test
    public void getRestaurant() throws Exception {
        mvc.perform(get("/restaurants/1004")).andExpect(status().isOk())
                .andExpect(content().string(containsString("\"name\":\"JOKER HOUSE\"")));

    }
}

모키토에 알아보기전 어노테이션을 보자.

 

@ExtendWith(SpringExtension.class) - > Spring Test를 위한 어노테이션(Spring 프레임워크 테스트 쓸 때 필수.)
@WebMvcTest -> mvc test를 위한 어노테이션 ( MockMvc ) // url, uri를 나타낼 컨트롤러만 쓰는듯하다.

 

실제로 RestaurantService는 함수만 있고 몸체를 코딩하지 않은 상태이다. 그러나 Mockito를 쓰고 가짜 객체를 만들어 주어 테스트를 진행한다.

Mockito의 장점은 원하는 컨트롤러나 서비스, 레파지토리 등의 자신의 작업 공간에서만 집중할 수 있어 코드의 정독성이 올라간다.

여기서 @BeforeEach setUp( )메서드를 통해 가짜 객체를 만들어 반환하여 각 테스트에 적용하고 있다.

대체적으로 @MockBean과 @Mock이 쓰이는데 자세한 내용은 아래 블로그를 참고하자.

일단 여기서 둘의 차이를 간단하게 말하자면@MockBean은 의존성 주입 타깃이 @SpringBootTest, @Mock은 @InjectMocks가 차이점.

(controller 단에서 Service는 SpringBootTest가 관리하니 @MockBean을 붙여주고, service 단에서는 직접 Repository를 주입해야하니 @Mock을 넣는 것 같다.)


https://cobbybb.tistory.com/16

 

Mockito @Mock @MockBean @Spy @SpyBean 차이점

예제 코드 https://github.com/cobiyu/MockitoSample Test Double이 왜 필요한 지부터 시작하는 기본적인 테스트 코드부터 한 단계씩 발전시켜나가며 Mockito의 어노테이션들의 정확한 쓰임새에 대해 살펴보겠습

cobbybb.tistory.com

 

@Service
public class RestaurantService {
    public List<Restaurant> getRestaurants() {
        return null;
    }

    public Restaurant getRestaurant(long id) {
        return null;
    }
}

실제로 널을 반환해도 컨트롤러단에서는 가짜객체로 테스팅하니 문제가 안된다.
그렇다면 Serivce 테스트를 따로 만들어야 하지만 Repository를 아직 만들지 않았다.

class RestaurantServiceTests {
    /*
    @Mock (cur : repository)
    Before => MockitoAnnotations.initMocks(this); // Spring에서 안넣어줄 경우.
     */
}

아까 설명했던 @Mock이 repository에 붙어 가짜 레파지토리를 만들고
이것을 RestaurantService에 초기화하여 사용하는 것이다.
@BeforeEach => MockitoAnnotations.initMocks(this);  // 사용전 초기화 과정도 중요.

 

'Spring' 카테고리의 다른 글

Java, Mybatis, Oracle 연동 코드  (0) 2022.05.29
Spring - <JSON> data patch  (0) 2022.01.22
Spring - Exception  (0) 2022.01.21
Spring - Validation  (0) 2022.01.21
JPA 활용.  (0) 2022.01.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함