티스토리 뷰

반응형

스프링 부트(Spring Boot)에서 컨트롤러(Controller)를 테스트 하는 방법에 대해서 기록해보겠습니다.

 

컨트롤러 테스트를 쉽게 하기 위해서 요청을 수행하고 응답을 만들어내는 Servlet API 모조(mock)객체를 사용합니다. 테스트에 사용되는 객체가 여러가지 존재하지만 대표적으로 MockMvc를 많이 사용합니다. (그리고 컨트롤러를 테스트 한다는 표현보다는 MVC를 테스트 한다는 표현을 주로 사용합니다.)

 

부트버전은 2.1.6을 사용했으며, Spring Web Starter이외에 별다른 의존 설정은 하지 않았습니다. (Spring Web Starter만 추가하면 아래와 같이 2가지 의존설정이 들어갑니다.)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

 

MockMvc를 주입받는 2가지 방법

  1. @SpringBootTest + @AutoConfigureMockMvc 애노테이션 붙이기

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class MyControllerTest {
     @Autowired
     private MockMvc mockMvc;
     ...
    
  2. @WebMvcTest 애노테이션 붙이기

    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class MyControllerTest {
     @Autowired
     private MockMvc mockMvc;
     ...

@SpringBootTest + @AutoConfigureMockMvc는 통합테스트를 할 때, @WebMvcTest는 MVC쪽만 슬라이스(slice) 테스트를 할 때 사용합니다.

 

 

+ 애노테이션을 이용한 자동 주입 이외에도, 스프링 프레임워크에서 사용하는 것 처럼 MockMvc를 직접 생성하는 방법도 사용 가능합니다. 직접 생성하게 되면 반복되는 코드를 설정할 수 있습니다. (예를들어 모든 예상 응답 status를 OK(200)으로 설정)

@Before
public void before() {
  	mockMvc = MockMvcBuilders.standaloneSetup(MyController.class)
          	    .alwaysExpect(MockMvcResultMatchers.status().isOk())
           	    .build();
}

 

MockMvc 사용하기

  1. "/hello" 경로로 get 요청보내고, 예상되는 응답 상태(status)로 OK(200) 설정하기

    @Test
    public void helloTest() throws Exception {
     mockMvc.perform(MockMvcRequestBuilders.get("/hello"))
             .andExpect(MockMvcResultMatchers.status().isOk());
    }
  2. 요청 보낼 때 Content-Type을 명시하기

    @Test
    public void helloTest() throws Exception {
     mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.TEXT_HTML))
             .andExpect(MockMvcResultMatchers.status().isOk());
    }
  3. 응답 받은 내용 print()하기

    @Test
    public void helloTest() throws Exception {
     mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.TEXT_HTML))
             .andExpect(MockMvcResultMatchers.status().isOk())
             .andDo(MockMvcResultHandlers.print());
    }
  4. Model "name" 키에 "siyoon"이라는 값이 담겨 있는지 확인하기

    @Test
    public void helloModelTest() throws Exception {
     mockMvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.TEXT_HTML))
             .andExpect(MockMvcResultMatchers.status().isOk())
             .andExpect(MockMvcResultMatchers.model().attribute("name", "siyoon"))
             .andDo(MockMvcResultHandlers.print());
    }

     

+ MockMvcRequestBuilders, MockMvcResultMatchers, MockMvcResultHandlers를 명시하지 않으면 아래와 같이 짧게 코드를 작성할 수 있지만 어떤 메소드가 있는지 알기 어려워 테스트코드 작성에 익숙하지 않다면 명시하는 것을 추천드립니다.

@Test
public void helloTest() throws Exception {
      mockMvc.perform(get("/hello").accept(MediaType.TEXT_HTML))
              .andExpect(status().isOk())
              .andDo(print());
}
반응형
댓글