본문 바로가기

Spring

MockMvc VS RestAssured

javable에 업로드 된 제 글을 옮겨온 글입니다. 😊

MockMvc와 RestAssured는 우리가 애플리케이션을 개발할 때 테스트를 편리하게 할 수 있게 해주는 유용한 테스트 도구이다. 이 두 가지 도구는 비슷하면서도 다르다. 상황에 맞게 적절한 테스트 도구를 활용할 수 있도록 눈에 띄는 몇 가지 차이점을 정리하고자 한다.

어느 것이 더 좋다는 정답은 없다.


사용 목적

MockMvc는 웹 애플리케이션을 애플리케이션 서버에 배포하지 않고도 스프링 MVC의 동작을 재현할 수 있는 라이브러리이며 대부분 Controller Layer Unit Test(단위 테스트)에 사용된다.

실제 서버 환경과 동일한 @SpringBootTest를 사용할 필요가 없으므로 @WebMvcTest를 통해 Presentation Layer Bean들만 불러온다. 그리고 그 외 Bean은 Mock 객체 설정을 해주어 순수한 Controller 로직을 테스트한다.

RestAssured는 REST 웹 서비스를 검증하기 위한 라이브러리이며 대부분 End-to-End Test(전 구간 테스트)에 사용된다.

@SpringBootTest로 실제 요청을 보내서 전체적인 로직을 테스트한다. 실제 요청 시 필요한 다양한 메서드도 제공한다.

하지만 RestAssured 만의 장점이 좋은 사람은 @SpringBootTest로 실제 요청을 보내는 전 구간 테스트를 할 수도 있고 MockMvc 만의 장점이 좋은 사람은 별도의 구성을 통해 @WebMvcTest로 Controller Layer 단위 테스트를 할 수도 있다.

어떤 Test에는 어떤 도구를 무조건 사용해야 한다는 정답은 없지 않을까 생각한다.


의존성

MockMvc는 Spring Framework Test 클래스 중 하나다. 즉 Spring test 의존성이 추가되어있는 경우 별도의 의존성 추가를 하지 않아도 사용할 수 있다. 반면에 RestAssured는 직접 의존성을 추가해줘야 한다.

RestAssured 의존성은 아래와 같이 추가할 수 있다.

dependencies {
    testImplementation 'io.rest-assured:rest-assured:3.3.0'
}

의존성을 추가하는 코드 한 줄 작성하는 게 뭐 어렵냐고 말할 수 있다. 하지만 의존성이 추가될수록 프로젝트는 점점 무거워진다. 필요하지 않은 의존성은 피할 수 있으면 피하는 게 당연히 좋다.

RestAssured를 사용하기 위해 의존성을 추가하는 순간이 온다면 현재 상황에서 RestAssured를 왜 사용하려는 지 한 번쯤 고민해보면 좋을 것 같다.


속도

RestAssured는 별도의 구성없이 @WebMvcTest를 사용하지 못한다. 사용하기 위해선 아래와 같이 @SpringBootTest로 수행해야 한다.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Test {
    @LocalServerPort
    public int port;

    @BeforeEach
    void setUp() {
        RestAssured.port = port;
    }
    ...

@SpringBootTest로 테스트를 수행하면 등록된 Spring Bean을 전부 로드하기 때문에 시간이 오래 걸린다. 반면에 @WebMvcTest는 Presentation Layer의 Bean들만 로드하기 때문에 시간이 상대적으로 빠르다.

MockMvc는 별도의 구성없이도 @WebMvcTest로 테스트를 수행할 수 있다. 물론 @SpringBootTest로도 수행할 수 있다. MockMvc를 @WebMvcTest로 수행하는 방법은 아래와 같다.

@WebMvcTest
@AutoConfigureMockMvc
public class ApiTest {
    @Autowired
    private MockMvc mockMvc;
    ...

속도가 빠른 @WebMvcTest와 별도의 구성이 필요 없는 MockMvc를 사용하는 게 무조건 좋은 것은 아니다. 상황에 따라 별도의 구성을 추가하는 비용을 지불하고 RestAssured를 사용할 수도 있고 Presentation Layer 외의 Bean을 여러 개 사용해야 한다면, 전부 Mock 객체로 처리해주는 비용과 빠른 테스트 시간 중 어느 것을 택할지도 고민해봐야 한다.


가독성

@Test
public void getMember() {
    given().
            accept(MediaType.APPLICATION_JSON_VALUE).
    when().
            get("/members/1").
    then().
            log().all().
            statusCode(HttpStatus.OK).
            assertThat().body("id", equalTo(1)); 
}

위의 예제는 RestAssured를 사용한 테스트이다.
RestAssured는 BDD 스타일로 작성할 수 있고 가독성이 좋다. 아래의 MockMvc와 비교해보자.

@Test
public void getMember() throws Exception {
    mockMvc.perform(get("/members/1")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id", Matchers.is(1)))
}

MockMvc와 비교해 봤을 때 BDD 스타일로 작성한 RestAssured가 더 쉽게 읽히는 것을 알 수 있다.

BDD로 작성한 테스트 코드는 비 개발자가 봐도 이해할 수 있도록 짜는 것을 권장한다.게다가 시나리오를 기반으로 해 이해하기가 더 쉽다. 이 두 가지를 생각했을 때, 사용자 관점의 인수 테스트는 RestAssured를 사용하는 것이 적절할 수 있다.

가독성과 더불어 두 개의 예제 코드 마지막 줄에서 확인할 수 있듯이 RestAssured는 MockMvc보다 json data를 쉽고 편하게 검증할 수 있다는 장점이 있다. 예제에서 보여준 메서드 이외에도 RestAssured는 MockMvc보다 json data 검증을 위한 다양한 메서드들을 제공한다.


결론

RestAssured와 MockMvc를 제외하고도 TestRestTemplate, WebTestClient 등등 더 다양한 테스트 도구들이 존재한다. 또한 이 글에 있는 내용이 두 가지 테스트 도구의 차이점 전부는 아니다. MockMvc는 Presentation Layer 테스트 시 세밀한 설정이 가능한 장점 등등 이 글에서 다루지 못한 차이점들이 있다.

테스트할 때 RestAssured와 MockMvc 또 다른 테스트 도구 들 중 어떤 것을 써야 한다는 정답은 없다. 중요한 것은 정답을 정해두지 말고 상황에 따라 어떤 것이 더 좋을지 항상 고민해보고 판단해야 한다는 것 아닐까?


참고자료

'Spring' 카테고리의 다른 글

WebMvcConfigurer addResourceHandlers 경로 설정  (0) 2020.09.12
@Mock vs @MockBean  (0) 2020.08.14
MockMvc VS RestAssured  (0) 2020.08.14
Tacademy JPA 강의 정리  (1) 2020.07.01
용어 정리  (0) 2020.04.21
Web server failed to start. Port 8080 was already in use 에러  (7) 2019.11.07