미운 오리 새끼의 우아한 개발자되기

[Spring Boot] Cloud Native Java - Test(2) 슬라이스 - @RestClientTest 본문

Spring & Spring Boot/Spring Boot

[Spring Boot] Cloud Native Java - Test(2) 슬라이스 - @RestClientTest

Serina_Heo 2022. 9. 28. 15:37

@RestClientTest 는 스프링의 RestTemplate 을 사용해서 REST 서비스와 통신하는 기능을 지원하는 애노테이션이다. 

아래 예제에서 @RestClientTest 가 붙어있는 단위 테스트가 나와있다. @RestClientTest({UserService.class}) 는 UserService 에서 REST 요청을 보내며, REST 요청을 보낼 수 있는 RestTemplate 을 사용할 수 있도록 자동 설정한다. getAuthenticatedUserShouldReturnUser 테스트 메소드에 사용되는 MockRestServiceServer는 UserService 안에서 RestTemplate 에 의해 전송되는 HTTP 요청을 처리하는 REST 서버의 흉내를 내는 모의 서버다. 모의 서버는 테스트 클래스 패스에 있는 user.json 파일을 읽어서 JSON 응답을 반환하도록 작성되어있다. 

MockRestServiceServer 를 이용해서 외부의 서비스를 가리키는 특정 URL에 대해 미리 정해진 user.json 의 값을 반환하도록 스텁할 수 있다. 이는 여러 서비스가 HTTP 로 협력하는 마이크로서비스 아키텍쳐에서의 테스트 작성을 쉽게 만들어준다. 

package demo.user;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.test.autoconfigure.web.client.AutoConfigueWebClient;
import org.springframework.boot.test.autoconfigure.web.client.RestClientTest;

import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.client.MockRestServiceServer;

import static org.assertj.core.api.Assertions.assertThat;

import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;

// 자동 설정 테스트 슬라이스 컨텍스트에 RestTemplate 을 등록한다. 
@RunWith(SpringRunner.class)
@RestClientTest({UserService.class})
@AutoConfigureWebClient(registerRestTemplate = true)
public class UserServiceTests {
    @Value("${user-service.host:user-service}")
    private String serviceHost;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private MockRestServiceServer server;
    
    @Test
    public void getAuthenticatedUserShouldReturnUser() {
    
        // RestTemplate 가 특정 URL 로 요청을 보낸 후 그 URL 로부터 받아오는 반환값을 Stub 한다
        this.server
            .expect(requestTo(
                String.format("http://%s/uaa/v1/me", serviceHost)))
            .andRespond(withSuccess(
                new ClassPathResource("user.json", getClass()),
                    MediaType.APPLICATION_JSON));
        
        User user = userService.getAuthenticatedUser();
        
        assertThat(user.getUsername()).isEqualTo("user");
        assertThat(user.getFirstName()).isEqualTo("John");
        assertThat(user.getLastName()).isEqualTo("Doe");
        assertThat(user.getCreatedAt()).isEqualTo(12345);
        assertThat(user.getLastModified()).isEqualTo(12346);
        assertThat(user.getId()).isEqualTo(0L);
    }
}

아래는 src/test/resource 안에 있는 user.json 이다.

{
    "username": "user",
    "firstName": "Jack",
    "lastName": "Frost",
    "email": "jfrost@example.com",
    "createdAt": 12345,
    "lastModified": 12346,
    "id": 0
}

[Reference] Cloud Native Java - Josh Long, Kenny Bastani, 책만