Spring/Test-Driven Develop

[Spring boot] 테스트 코드 작성 (2) - Mock, Mockito, MockMVC

민돌v 2022. 2. 3. 23:53

Spring 테스트 코드 작성해보기!

 

목차

  1. Junit 이란
  2. Junit 사용설정
  3. Junit 어노테이션
  4. Junit 사용법
  5. Assert 메소드
  6. @Nest사용 엣지 케이스 확인

 


1, Mock vs Mockito vs MockMVC

 

1) Mock 이란,

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

 

2) Mockito 란,

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

 

3) MockMVC

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

 


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

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

 

서로 연관성이 깊은 Spring 구조

 

위의 그림처럼 연관성이 깊은 스프링 구조상 모듈 단위의 이상적인 단위테스트를 위해 각각의 모듈만 테스트하기위해

명시만 되어있는 가짜 객체를 이용해 주는 것이다.

 

Mock 객체를 이용


 

3. Controller, Service 테스트 하기

 

1) Mockito 의존성 추가

build.gradle의 dependencies에 mockito 라이브러리를 추가해준다.

testImplementation 'org.mockito:mockito-all:1.9.5'



PostController

//@SpringBootTest     //Junit5 - Runwith 포함
@RunWith(SpringRunner.class)
//Controller + Spring security 추가
@WebMvcTest(controllers = {PostController.class}, includeFilters = @ComponentScan.Filter(classes = {EnableWebSecurity.class}))
//@AutoConfigureMockMvc //@Service, @Repository가 붙은 객체들도 모두 메모리에 올림
@RequestMapping("/api")
class PostControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void postList_GET() throws Exception {
        MultiValueMap<String, String> query_param = new LinkedMultiValueMap<>();
        query_param.add("page","1");
        query_param.add("sorted","createdAt");

        mockMvc.perform(MockMvcRequestBuilders.get("/posts?page=1&sorted=createdAt"))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());

        mockMvc.perform(MockMvcRequestBuilders.get("/posts").params(query_param))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print());
    }

}

 

✔️ 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())

  • 요청/응답 전체 메세지를 확인할 수 있습니다.

 

 


*참고

mock, mokito : https://gdblog91.tistory.com/11

MockMVC Controller ; https://shinsunyoung.tistory.com/52

MockMVC 사용법 : https://siyoon210.tistory.com/145

MockMVC perform MockRequestBuilder : https://zzang9ha.tistory.com/382