자바 MockWebServer로 멱등성 있는 테스트코드 작성하기

ssongkim·2023년 2월 19일
1

테스트코드

목록 보기
3/4

Overview

우리 팀에서 관리하는 서버 중에 외부의 이미지를 수집하기 위해 이미지 URL을 받아 이를 우리가 원하는 사이즈로 가공하여 S3에 업로드하는 역할을 하는 서버가 있다.

이러한 프로세서에 대해 테스트코드를 작성하고자 하니,, 문제점이 있었다. 이미지 URL은 언제든 깨질 수 있어 테스트코드 작성 시 가장 중요한 원칙 중 하나인 멱등성 보장이 어려웠다.

그래서 이미지를 받아오는 외부 서버와 통신하는 부분을 모킹서버를 활용해 해결하였다.

MockServer 라이브러리 선정하기

처음에 두가지 라이브러리 중 고민을 하였다.

  • MockServer Netty
  • okhttp MockWebServer

스프링 진영에서는 okhttp MockWebServer를 활용해 모킹서버를 구축하는 것을 권장(링크)한다고 하여 okhttp MockWebServer를 사용하게 됐다.

시작하기

1. 의존성 추가

// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
testImplementation 'com.squareup.okhttp3:okhttp:4.10.0'
// https://mvnrepository.com/artifact/com.squareup.okhttp3/mockwebserver
testImplementation 'com.squareup.okhttp3:mockwebserver:4.10.0'

2. MockServerSupport 작성

public class MockServer
{
    private final MockWebServer mockWebServer;
    public MockServer() throws IOException
    {
        this.mockWebServer = new MockWebServer();
        this.mockWebServer.start();
    }
 
    public void shutdown() throws IOException
    {
        this.mockWebServer.shutdown();
    }
 
    public String getMockServerBaseUrl()
    {
        return "http://localhost:" + this.mockWebServer.getPort();
    }
 
    public void insertNormalImageResponse()
    {
        try
        {
            this.mockWebServer.enqueue(new MockResponse()
                .addHeader("Content-Type:image/png")
                .setBody(getBinaryFileAsBuffer("seed/image/normal-image.jpg")));
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
 
    public static Buffer getBinaryFileAsBuffer(String path) throws IOException {
        ClassPathResource classPathResource = new ClassPathResource(path);
        byte[] fileData = FileUtils.readFileToByteArray(classPathResource.getFile());
 
        Buffer buf = new Buffer();
        buf.write(fileData);
        return buf;
    }
}

insertNormalImageResponse 메서드를 보면 mockserer에 큐를 넣듯 내가 기대하는 MockResponse를 넣는 것을 볼 수 있다.

그렇다! MockWebServer는 어떤 url이든 베이스 URL을 호출하면 사전에 큐에 넣어둔 response를 FIFO처럼 차근차근 꺼내 보여주는 방식으로 모킹한다.

3. 사용하기

class ...Test {
private MockServer mockServer;
 
 
  @BeforeEach
  void beforeTest() throws IOException
  {
      this.mockServer = new MockServer();
  }

  @AfterEach
  void afterTest() throws IOException
  {
      this.mockServer.shutdown();
  }

 
 
  @Test
  @DisplayName("만약 URL이 정상이여서 다운로드 가능하다면 다운로드에 성공한다.")
  void successWhenItDownload()
  {
      // given
      mockServer.insertNormalImageResponse();
      String url = mockServer.getMockServerBaseUrl();


      // when
      테스트대상.download(url);
      ...
      // then
      ...
  }

}

given 절에서 MockServer 큐에 내가 기대하는 response를 넣었고, 이를 when 절에서 해당 모킹서버와 통신하면 기대하는 response가 나오는 구조이다.

profile
鈍筆勝聰✍️

0개의 댓글