본문 바로가기

Back End/Spring Boot

[Test] RestAssured vs Mock MVC

RestAssured vs Mock MVC


개요

  RestAssured와 Mock MVC에 대해 알아본다.

 

목차

 

소개

1. RestAssured란?

Restful 애플리케이션의 http Endpoint의 테스트를 편리하게 하기 위한 Java의 Library 테스트 도구

 

RestAssured의 장점
1. Given, When, Then 구문을 사용하여 코드를 직관적으로 작성가능하다.

2. Json 혹은 XML 형태로 Response Data를 Parsing 하여, Header, Body, Status 등을 검증할 수 있다.

3. Restful Application에 특화되어 있으며, Http Endpoint와의 통신을 간단하게 설정해, 다양한 Http Method 와의 요청을 지원한다.

 

 

RestAssured Code 예시
public Boolean testName(String name, String nickName) {

	int id = 외부함수호출Class.excute(name);
	
	if (verifyId(id, nickName)) {
		~
	}
}
// 위의 경우 verifyId의 Parameter 값을 넣어줄때, name에 따른 id를 세팅해주고
// id와 nickName을 통해 함수를 검증해야 옳바른 결과를 얻을 수 있다.
// 이 때, 외부함수호출Class을 호출하면 name에 따른 id를 알 수 없으므로
// 위와 같은 경우에 RestAssuredTest를 사용해 직접적으로 Url을 호출해 테스트를 진행 가능하다.

 

위의 코드와 같은경우 외부함수호출Class가 많은 의존성을 갖고 있을 경우, 불필요한 의존성 주입을 해주어야한다.
이때, Http EndPoint 통신을 할 수 있는 RestAssured를 활용해 아래와 같이 Test Code를 작성할 수 있다.

 

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

@Test
public void 외부호출값검증() {
	//given
	String id = "test";

	//when
	ExtractableResponse<Response> res = this.외부_URL_호출(id);

	//then -> 예측한 statusCode 입력하여 Test or 예측한 값과 return값 비교
	Assertions.assertEquals(res.statsCode(), 200);
} 

//RestAssured Test
public ExtractableResponse<Response> 외부_URL_호출(String input) {
    Map<String,String> id = new HashMap<>();
    id.put("id", input);

	//외부 Url을 호출해서, 원하는 값을 가져와서 로직을 구성해볼수도 있고,
	//개발하신 로컬 Url을 호출해서, 테스트도 가능합니다.
    return RestAssured
		.given().log().all()
		.baseUri("https://호출할 baseUri")
		.contentType(MediaType.APPLICATION_JSON_VALUE)
        .when()
		.get("/getId/{id}",id)
		.then().log().all()
		.extract();
}

 

이를 통해, 실제 Http Endpoint 호출을 통해 더 정확한 값을 가져와서 비교할 수 있게 됨으로, 더 정확한 테스트가 가능하게 된다.

 

2. Mock MVC란?

MockMVC는 Spring의 MVC 동작을 재현할 수 있는 Controller Layer의 기능을 테스트하는데 이점이 있는 Library 테스트 도구

 

Mock MVC의 장점
1. 실제 서버를 구동하지 않아도, Mock을 통해 데이터를 제공하며 경량화된 테스트환경을 제공해준다.

2. Mock을 활용하여, 다른 컴포넌트와의 의존성 주입 없이 Controller의 독립적인 기능을 테스트 할 수 있다.

3. Http의 요청도 Mock MVC를 통해 주고 받으며 실제 서버와 유사한 환경에서의 테스트가 가능하다.

 

Mock MVC 코드 예시
public class depth1 {
  private final Depth2 depth2;
	private final String name;

	public depth1(Depth2 depth2, String name) {
		this.depth2 = depth2;
		this.name = name;
	}

	public String depth1_method(String result) {
		String resName = depth2.getNameByResult(result);
		if (resName.equals("Success")
			return "Clear";
		return "Failure"
}

public class depth2 {
  private Depth3 depth3;
	private String name;

	public depth2(Depth3 depth3) {
		this.depth3 = depth3;
	}

	public String getNameByResult(String result) {
		this.depth3.setResult(result);
		return post('/name/{result}',this.depth3.getResult()); //post 요청을 통해 name을 가져오는 코드
}

public class depth3 {
  private final Depth4 depth4;

	public depth3(Depth4 depth4) {
		this.depth4 = depth4;
	}
}

 

위의 코드는 depth1의 depth1_method를 검증하기 위한 Test Code를 작성하기 위해서는 depth1, depth2, depth3를 호출하여 의존성을 주입해주어야 한다. 위의 코드를 Mock MVC를 활용해 테스트 코드를 작성하면 아래와 같다.

 

public class Depth1Test {
    @Mock
    private Depth2 depth2;

    @Mock
    private Depth3 depth3;

    @InjectMocks
    private Depth1 depth1;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.openMocks(this);
    }

    @Test
    public void testDepth1Method() {
        String result = "Success";
        when(depth2.getNameByResult(result)).thenReturn("Success");
        String actual = depth1.depth1_method(result);
        assertEquals("Clear", actual);
    }
}

 

다소 복잡할 수 있는 의존성 주입을 @Annotaion을 활용해 간결화된 Test Code를 작성할 수 있게 도와준다.

 

3. Mock MVC vs RestAssured

 

그렇다면 둘의 가장 큰 차이는 무엇일까?
1. Mock MVC가 테스트하고자 하는 코드는 서버 측 코드 즉, Controller Layer단의 기능이다.
하지만, RestAssured에서 테스트 하고자 하는 코드는 주로 클라이언트측에서 사용하는 코드, 즉 Http Endpoint 에서 받는 데이터의 값들이라는 차이가 존재한다.

2. Mock MVC는 주로 Spring과 함께 의존성 주입(DI)등과 함께 사용되지만, RestAssured Test는 JAVA 기반의 Restful한 Application들에 모두 사용이 가능하다.

3. Mock MVC는 주로 서버의 컨트롤러를 직접 호출하며 함수의 단위테스트 혹은 통합테스트를 검증하는데 사용되지만,
RestAssuredhttp 요청과 응답에 관한 시뮬레이션 테스트 및 외부 API 호출시의 응답값 테스트등에 사용된다.

 

요약하자면, 둘의 가장 큰 차이는 Mock MVC는 Controller Layer단에 구현된 코드들의 기능을 테스트하는데에 초점이 맞춰져 있다면, RestAssured는 Http Endpoint를 통해 실제 Http와의 통신을 통해 받아오는 값들을 활용해 검증하는데에 초점이 맞추어져 있다.