Jin's Dev Story

[SpringBoot] Mock 테스트 본문

Web & Android/SpringBoot

[SpringBoot] Mock 테스트

woojin._. 2023. 7. 28. 12:59

1. Mock vs Mockito vs MockMVC

1) Mock

  • 테스트를 위한 가짜 객체
  • 실제 객체를 만들기에는 비용과 시간, 의존성이 크게 걸쳐져 있어 테스트 시 제대로 구현하기 어려울 경우 만드는 가짜 객체

2) Mockito

  • Mock Object를 간편하게 만들게 해주는 라이브러리
  • Mock 객체를 만들기 위해서 사용되는 시간을 줄이기 위해, 자동으로 생성해주는 라이브러리
  • Mock 객체 직접 구현하지 않아도 되게 함

3) MockMVC

  • 스프링에서 MVC 테스트를 하기 위한 방법을 논의하여 Spring-test모듈을 스프링 프레임워크에 더한 것
  • 브라우저에서 요청과 응답을 의미하는 객체로서 Controller 테스트를 용이하게 해주는 라이브러리
  • 기존의 MockHttpServletRequest, MockHttpServletREsponse를 활용한 단위테스트에서 발전

2. Mock 객체를 사용하는 이유

  • 이상적으로, 각 테스트 케이스는 서로 분리되어야 함
  • 이를 위해 가짜 객체를 생성하는 것도 좋은 방법

3. Controller, Service 테스트 하기

1) Mockito 의존성 추가

  • build.gradle의 dependencies에 mockito 라이브러리를 추가
testImplementation 'org.mockito:mockito-all:1.9.5'
@SpringBootTest
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application-test.properties")
class ItemControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    @DisplayName("상품 등록 페이지 권한 테스트")
    @WithMockUser(username = "admin", roles = "ADMIN")
    public void itemFormTest() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("admin/item/new"))
                .andDo(print())
                .andExpect(status().isOk());
    }

    @Test
    @DisplayName("상품 등록 페이지 일반 회원 접근 테스트")
    @WithMockUser(username = "user", roles = "USER")
    public void itemFormNotAdminTest() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/admin/item/new"))
                .andDo(print())
                .andExpect(status().isForbidden());
    }
}

 

mockMvc의 메소드

1) perform()

  • 요청을 전송하는 역할을 합니다. 결과로 ResultActions 객체를 받으며, ResultActions 객체는 리턴 값을 검증하고 확인할 수 있는 andExcpect() 메소드를 제공

2) get("/mock/blog")

  • HTTP 메소드를 결정할 수 있습니다. ( get(), post(), put(), delete() )
  • 인자로는 경로를 보내줌

3) params(info)

  • 키=값의 파라미터를 전달할 수 있음
  • 여러 개일 때는 params()를, 하나일 때에는 param()을 사용

4) andExpect()

  • 응답을 검증하는 역할
  • 상태 코드 ( status() )
    • 메소드 이름 : 상태코드
    • isOk() : 200
    • isNotFound() : 404
    • isMethodNotAllowed() : 405
    • isInternalServerError() : 500
    • is(int status) : status 상태 코드
  • 뷰 ( view() )
    • 리턴하는 뷰 이름을 검증
    • ex. view().name("blog") : 리턴하는 뷰 이름이 blog인가?
  • 리다이렉트 ( redirect() )
    • 리다이렉트 응답을 검
    • ex. redirectUrl("/blog") : '/blog'로 리다이렉트 되었는가?
  • 모델 정보 ( model() )
    • 컨트롤러에서 저장한 모델들의 정보 검증
  • 응답 정보 검증 ( content() )
    • 응답에 대한 정보를 검증

5) andDo(print())

  • 요청/응답 전체 메세지를 확인할 수 있음