이번 포스트에서는 Rest Client에 대한 Slide 테스트를 위한 @RestClientTest를 사용해보자.
Rest Client Test
@RestClientTest
Rest Client는 통상 서비스에 작성하며 원격지에서 제공하는 REST API를 사용하는 클라이언트이 @RestClientTest는 이를 테스트하기 위한 slice test 도구이다.
@Target(ElementType.TYPE)
@BootstrapWith(RestClientTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(RestClientTypeExcludeFilter.class)
@AutoConfigureCache
@AutoConfigureWebClient
@AutoConfigureMockRestServiceServer
@ImportAutoConfiguration
public @interface RestClientTest {
Class<?>[] components() default {};
}
- @TypeExcludeFilters(RestClientTypeExcludeFilter.class):RestClient와 관련된 빈들만 로딩한다. JackSon, GSON 등 json 처리 빈이나 RestTemplateBuilder등이 포함된다.
- @AutoConfigureCache: 기본 CacheType으로 CacheType.NONE을 설정해서 데이터를 캐싱하지 않는다.
- @AutoConfigureWebClient: WebFlux 관련 라이브러리인 WebClient를 구성한다.
- @AutoConfigureMockRestServiceServer: 원격지 서버를 mocking하는 MockRestServiceServer를 생성한다.
- components 속성: 테스트하려는 대상 서비스를 등록한다.
대상 서비스 작성
먼저 테스트 대상인 Rest Client를 작성해보자.
@Service
@RequiredArgsConstructor
public class RestClientService implements InitializingBean {
private final RestTemplateBuilder builder;
private RestTemplate template;
public final String API_SERVER = "http://some-server.com";
public Map<String, Object> getUserFromPlaceHolder(String userId) {
ParameterizedTypeReference<Map<String, Object>> refType
= new ParameterizedTypeReference<>() {};
ResponseEntity<Map<String, Object>> res
= template.exchange(API_SERVER + "/users/" + userId, HttpMethod.GET, null, refType);
return res.getBody();
}
@Override
public void afterPropertiesSet() throws Exception {
DefaultUriBuilderFactory uriBuilder = new DefaultUriBuilderFactory(API_SERVER);
this.template = builder.uriTemplateHandler(uriBuilder)
.defaultHeader("Authorization", "some token").build();
}
}
이 서비스가 테스트 되기 위해서는 API_SERVER의 서버가 필요한데 여기에 종속되지 않으려면 MockServer가 필요하다.
테스트
@RestClientTest(value = RestClientService.class)
public class T_9330_RestClientTest {
@Autowired
RestClientService service;
@Autowired //원격의 서버를 mocking 해줌
MockRestServiceServer server;
@Test
public void 사용자_조회() throws JsonProcessingException {
// given
String userId="hong";
// server mocking
ObjectMapper objMapper = new ObjectMapper();
Map<String, Object> expectResult = Map.of("name", "hong", "age", 20);
server.expect(requestTo(service.API_SERVER+ "/users/"+userId))
.andRespond(withSuccess(objMapper.writeValueAsString(expectResult), MediaType.APPLICATION_JSON));
// when
Map<String, Object> result =service.getUserFromPlaceHolder(userId);
// then
assertThat(result.get("name")).isEqualTo("hong");
assertThat(result.get("age")).isEqualTo(20);
}
}