Jeomxon's Tech Note

RestAssured와 MockMvc중 어떤 걸 써야할까? 본문

Spring/Test

RestAssured와 MockMvc중 어떤 걸 써야할까?

저문(jeomxon) 2023. 5. 10. 03:13

컨트롤러 단을 테스트하면서 RestAssured를 사용하기도 하고, mockMvc도 사용을 해봤다.

각각의 미션마다 '이걸 사용하자!'라고 생각하고 사용하긴 했는데 막상 큰 이유는 없었던 것 같다.

어떤 상황에 어떤 걸 써야 잘 썼다고 할 수 있을까?

 

사실 정답은 없다고 생각한다.

적절한 상황에 맞춰서 잘 사용하면 된다는 것이 답이 될 것이다.

그런데 학습을 하고 있는 나의 입장에서는 적절한 상황이라는 말이 잘 와닿지 않았다.

그래서 나만의 기준을 세우고자 글을 써보면서 정리하려고 한다.

 

보통 RestAssured를 사용하는 경우는 @SpringBootTest가 붙은 테스트였다.

여기서 @SpringBootTest를 사용하면 실제 스프링부트 서버환경을 제공하게 되는데,

이는 당연히도 테스트가 무거워지게 된다.

모든 스프링 빈들을 가져와서 로드하기 때문이다.

즉 @SpringBootTest를 통해서 통합 테스트를 할 수 있고, RestAssured도 그에 맞게 사용했다.

 

반면 MockMvc는 @WebMvcTest라는 어노테이션과 함께 사용했다.

이는 단위 테스트를 위한 용도라고 볼 수 있는데, 주로 컨트롤러를 테스트하는데 이용한다.

아무래도 단위 테스트를 위한 용도이기 때문에 모든 스프링 빈을 가져오지 않는다.

Presentation Layer 빈만 불러오기 때문에 @SpringBootTest를 사용한 테스트보다 가볍다.

 

아래는 사용 예시이다.

@SpringBootTest + RestAssured

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RacingGameWebControllerTest {

    @MockBean
    private RacingGameService racingGameService;

    @LocalServerPort
    int port;

    @BeforeEach
    void setUp() {
        RestAssured.port = port;
    }
    
    ...
    
    @DisplayName("전체 레이싱 결과 조회 요청을 확인한다.")
    @Test
    void findPlayingHistory() {
        RestAssured.given().log().all()
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .when().get("/plays")
                .then().log().all()
                .statusCode(HttpStatus.OK.value());
    }
    
    ...

@WebMvcTest + MockMvc

@Import(BasicAuthorizationExtractor.class)
@WebMvcTest(PageController.class)
class PageControllerTest {

  	...

    @Autowired
    private MockMvc mockMvc;

    @DisplayName("'/'로 GET 요청을 했을 때 index template을 반환한다.")
    @Test
    void index() throws Exception {
        
        ...
        
        mockMvc.perform(get("/"))
                .andExpect(status().isOk())
                .andExpect(model().attributeExists("products"))
                .andExpect(model().attribute("products", hasItem(hasProperty("id", is(1L)))))
                .andExpect(model().attribute("products", hasItem(hasProperty("name", is("치킨")))))
                .andExpect(model().attribute("products", hasItem(hasProperty("imageUrl", is("image.url")))))
                .andExpect(model().attribute("products", hasItem(hasProperty("price", is(10000)))))
                .andExpect(view().name("index"));
    }
   
   ...

 

위의 코드예시에서 드러나는 특징들이 있다.

먼저 RestAssured는 BDD(Behavior Driven Development)를 기반으로 테스트가 작성된다.

given, when, then의 패턴을 가지고 가는데, 이는 가독성 측면에서 훨씬 장점이 있다.

 

MockMvc는 스프링에서 제공하는 라이브러리이다.

MockMvc를 통해서 단위테스트, 그리고 통합테스트도 진행할 수 있다는 장점이 있다.

(예시에는 없지만 MockMvc는 @SpringBootTest와도 함께 사용할 수 있어 통합테스트도 가능)

 

추가적으로 각각의 장단점이 존재하는데 가장 와닿았던 것은

BDD와 통합테스트 vs 가벼운 단위테스트의 느낌이었다.

 

결론적으로 정답은 없다.

어느 것을 사용하든 문제가 되지 않는다.

하지만 각각의 장단점을 명확하게 이해하고,

통합테스트, 단위테스트, 인수테스트가 필요한 각 상황에 맞춰서 사용하는 것이 좋아보인다.

 

 

 

참고한 글

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/web/servlet/WebMvcTest.html

 

WebMvcTest (Spring Boot 3.0.6 API)

Annotation that can be used for a Spring MVC test that focuses only on Spring MVC components. Using this annotation will disable full auto-configuration and instead apply only configuration relevant to MVC tests (i.e. @Controller, @ControllerAdvice, @JsonC

docs.spring.io

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html

 

SpringBootTest (Spring Boot 3.0.6 API)

Application arguments that should be passed to the application under test.

docs.spring.io

https://github.com/rest-assured/rest-assured/wiki/Usage

 

Usage

Java DSL for easy testing of REST services. Contribute to rest-assured/rest-assured development by creating an account on GitHub.

github.com

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/servlet/MockMvc.html

 

MockMvc (Spring Framework 6.0.8 API)

Perform a request and return a type that allows chaining further actions, such as asserting expectations, on the result.

docs.spring.io

 

'Spring > Test' 카테고리의 다른 글

Mockito를 써보면서...  (0) 2023.04.24