tools & libs/단위테스트(junit, spock)

[spring test] 8. Rest Client Test

  • -
반응형

이번 포스트에서는 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);
  }
}

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.