WireMock

외부 API 를 테스트할 때 유용한 도구인 WireMock 에 대해 알아보자.
WireMock 은 HTTP mock server 이다. 핵심적인 기능으로,

  • 특정 요청 (stubbing) 에 대해 미리 준비된 응답을 할 수 있고,
  • 유입된 요청을 capture 하여 verification 이 가능하다.

Setup

wiremock 을 사용하기 위해 필요한 dependency 를 추가하자.

Basic Usage

JUnit5 를 기준으로 테스트해보자. @WireMockTest 로 간단히 테스트 가능하다.
WireMockRuntimeInfo 를 통해서는, port number 나 base URL 등의 정보를 얻을 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@WireMockTest
class WireMockTest {

@Test
fun `wiremock basic usage`(wmRuntimeInfo: WireMockRuntimeInfo) {
// given
stubFor(get("/static-dsl").willReturn(ok()))

// when
val testRestTemplate = TestRestTemplate()
val response: ResponseEntity<String> = testRestTemplate.getForEntity(
"${wmRuntimeInfo.httpBaseUrl}/static-dsl",
String::class.java
)

// then
assertEquals(200, response.statusCodeValue)
}
}

Stub

WireMock 의 핵심 기능은, 기준과 일치하는 요청에 대해 미리 준비된 HTTP 응답을 반환하는 기능이다.

아래 코드는,
요청 URL 이 query parameters 를 포함해서 /some/thing 과 정확히 일치할 때 다음과 같이 응답한다.

  • response status code: 200
  • response body: “Hello world!”
  • Content-Type header: text-plain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@WireMockTest
class WireMockTest {

@Test
fun `wiremock basic stub`(wmRuntimeInfo: WireMockRuntimeInfo) {
// given
stubFor(
get(urlEqualTo("/some/thing"))
.willReturn(
aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("Hello world!")
)
)

// when
val testRestTemplate = TestRestTemplate()
val response1 = testRestTemplate.getForEntity(
"${wmRuntimeInfo.httpBaseUrl}/some/thing",
String::class.java
)
val response2 = testRestTemplate.getForEntity(
"${wmRuntimeInfo.httpBaseUrl}/some/thing/else",
String::class.java
)

// then
assertEquals(200, response1.statusCodeValue)
assertEquals("Hello world!", response1.body)
assertTrue(response1.headers["Content-Type"]!!.contains("text/plain"))

assertEquals(404, response2.statusCodeValue)
}
}


Comments