[네이버 클라우드 서포터즈] 스텝페이 API 테스트편

himitery·2022년 11월 11일
0

스텝페이 API 연결편에서 연결한 스텝페이 API를 테스트하는 방법에 대한 과정을 담았습니다.

'오늘의 빵' 서비스에서는 테스트 코드를 작성하여 작성한 코드가 정상적으로 작동하는지 확인하고 있습니다. 문제는 스텝페이의 API를 사용하는 Service도 같이 테스트가 진행되기 때문에, 테스트를 실행시킬 때마다 스텝페이에 요청을 보내고 데이터가 만들어지게 됩니다. 이러한 문제를 해결하고자, 스텝페이 API를 요청하는 ServiceMocking하였습니다.

처음에는 Mockito를 사용하여 스텝페이 API 요청을 보내는 메소드 자체를 직접 Mocking 하였습니다.

@MockBean
private SteppayCustomerServiceImpl steppayCustomerService;

@Test
public void method_name() {
	when(steppayCustomerService.createCustomer(any(SteppayCreateCustomerRequest.class)))
          .thenReturn(
              SteppayCustomerResponse.builder()
                  .id(1000)
                  .createdAt(LocalDateTime.now())
                  .modifiedAt(LocalDateTime.now())
                  .name("test_name")
                  .email("email@email.com")
                  .phone("01012345678")
                  .build()
          );
   }
}

위와 같은 방법으로 steppayCustomerService.createCustomer() 메소드를 Mocking 하였을 때, 특정 값을 반환하도록 하였습니다.
문제는 저러한 Mocking 처리를 최소한 해당 테스트 클래스에서 스텝페이 API를 사용하는 개수만큼 해야 한다는 것입니다. 실제 테스트 코드에서는 @BeforeEach를 통해 적용했음에도 불구하고 n개의 스텝페이 API를 사용하면 n개의 Mocking 작업이 필요했습니다.

그래서 방법을 바꾸어 Mock Class를 만들기로 하였습니다. 기존에는 SteppayCustomerService의 인터페이스와 SteppayCustomerServiceImpl이라는 구현체로만 이루어져어 있었다면, SteppayCustomerServiceMock이라는 Mocking을 위한 구현체를 추가로 구현하였습니다.

/* SteppayCustomerService */

public interface SteppayCustomerService {

    SteppayCustomerResponse createCustomer(SteppayCreateCustomerRequest request);
}
/* SteppayCustomerServiceImpl */

@RequiredArgsConstructor
public class SteppayCustomerServiceImpl implements SteppayCustomerService {

    private final RestTemplate template;

    @Override
    public SteppayCustomerResponse createCustomer(SteppayCreateCustomerRequest request) {
        return template.postForObject(
            "/customers",
            request,
            SteppayCustomerResponse.class
        );
    }
}
/* SteppayCustomerServiceMock */

public class SteppayCustomerServiceMock implements SteppayCustomerService {
    
    @Override
    public SteppayCustomerResponse createCustomer(SteppayCreateCustomerRequest request) {
        return SteppayCustomerResponse.builder()
            .id((long) (Math.random() * 10_000))
            .createdAt(LocalDateTime.now())
            .modifiedAt(LocalDateTime.now())
            .name(request.getName())
            .email(request.getEmail())
            .phone(request.getPhone())
            .build();
    }
}
/* ApplicationConfig */

@TestConfiguration
public class ApplicationConfig {

    @Bean
    public SteppayCustomerService steppayCustomerService() {
        return new SteppayCustomerServiceMock();
    }
}

SteppayCustomerServiceMock 클래스는 입력 값에 따라 일정하거나 랜덤한 값으로 반환 객체를 만들어 반환합니다. 그리고 test 아래에 있는 ApplicationConfig에서 Bean으로 등록해주었습니다.

Mock class를 같은 인터페이스를 상속받아 구현하고, 특정 Profile에서만 활성하였습니다. 이렇게 구현했을 때의 장점은 테스트 클래스마다 각각 Mocking하는 과정 없이 그냥 사용할 수 있습니다. (Spring boot에서 Mock class가 Bean으로 생성되어 있어, 해당 Mock class가 DI되기 떄문입니다.)

이렇게 만들어진 테스트를 실행하였을 때, 스텝페이 API에 의존하지 않고 순수하게 '오늘의 빵'의 로직만을 테스트할 수 있게 되었습니다. 이제 Github Actions가 실행될 때마다 스텝페이에 API를 호출하지 않게 되었습니다!! 😁

0개의 댓글