공부하는 블로그

Spring | MockServer 본문

Spring

Spring | MockServer

치킨닮은닭 2023. 9. 24. 23:33

MockServer?

 테스트 코드를 작성하다보면 다른 서버로 웹 요청을 날리는 로직에 대해 어떻게 처리해야할지 고민하게 된다. 실제 웹 서버로의 요청을 날리기엔 네트워크 상태에 따라 테스트 케이스가 깨지는 경우도 발생하고, 실제 웹 서버에 테스트용 데이터가 전송되는 것도 이상하다. 결제 서비스의 경우 실제 요청이 진행될 경우 결제가 일어나게 되기도 한다. 이를 막기 위해서는 웹 서버를 Mocking 해야하는 상황이 발생한다.

 

 이 때, Mock Server 라이브러리를 사용하면 간단하게 요청을 받을 웹 서버를 생성 가능하다.

Spring Test With MockServer

 MockServer를 이용해서 다른 웹 서버로 요청을 날리는 클라이언트에 대해 단위 테스트를 진행해보자.

 

 먼저 MockServer 라이브러리 의존성을 build.gradle에 추가한다.

// build.gradle

dependencies {
  testImplementation 'org.mock-server:mockserver-netty:5.15.0'
}

 간단한 테스트를 작성해보자!

@DisplayName("결제 클라이언트 단위 테스트")
class PayClientTest {
  private static ClientAndServer mockWebServer; // mock 웹 서버. (여기선 PG사 서버)

  private PayClient payClient; // PG사 요청 클라이언트.

  private ObjectMapper objectMapper = new ObjectMapper(); // body json string 매핑용.

  @BeforeAll
  public static void setUp() {
    mockWebServer = ClientAndServer.startClientAndServer(); // mock server start
  }

  @AfterAll
  public static void destroy() {
    mockWebServer.stop(); // mock server stop
  }

  @BeforeEach
  void initialize() {
    String baseUrl = String.format("http://localhost:%s", mockWebServer.getPort());
    easyPayClient = new PayClient(baseUrl); // 결제 클라이언트에 mock 웹 서버 URL로 세팅
  }

  @Test
  @DisplayName("결제 실패")
  void givenBadResquestThenThrowException() throws Exception {
    // given
    final PaymentRequest request = PaymentRequestFixture.invalid(); // PG 요청 Fixture
    final String requestStr = objectMapper.writeValueAsString(request);

    final PaymentResponse response = PaymentResponseFixture.badRequest(); // PG 응답 Fixture
    final String responseStr = objectMapper.writeValueAsString(response);

    mockWebServer
        .when(
            request() // 요청 Spec 정의
                .withMethod("POST")
                .withPath("/pay")
                .withHeader(new Header(HttpHeaders.AUTHORIZATION, "this_is_api_key"))
                .withContentType(MediaType.APPLICATION_JSON)
                .withBody(requestStr)
        )
        .respond(
            response() // 원하는 응답 Spec 정의
                .withStatusCode(400)
                .withBody(responseStr)
        );

    // when, then
    assertThrows(PayFailException.class, // 에러 응답 시 발생시키도록 정의한 exception.
        () -> payClient.pay(request));
  }
}

'Spring' 카테고리의 다른 글

Spring | @TransactionalEventListener  (0) 2023.09.17
Spring | Application Event  (0) 2023.09.10
Spring | BDD - Given / When / Then  (0) 2023.09.03
Spring | Mockito Unit Test  (0) 2023.08.27
Spring | Annotations  (0) 2020.09.29
Comments