在使用@WireMockTest](https://dev.to/rogervinas/testing-with-wiremocktest-3da0)进行的[测试中,我展示了一个使用**@WireMockTest** 和WireMockExtension 在我们的测试中模拟API 的演示。

但是 WireMock 有一个官方 Docker 镜像,我们也试试吧! 🤩

[图](https://res.cloudinary.com/practicaldev/image/fetch/s--qqUjhPMK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/lq53jy6ujyz4iwho7nw9.png)

GitHub 徽标rogervinas/线模测试

🤹 WireMock 测试

  • 码头工人撰写

  • 使用 Testcontainers 进行应用程序测试

*静态存根

*动态存根

  • 使用 Docker Compose 运行的应用程序

码头工人撰写

我们在docker-compose.yml中配置这两个容器:

version: "3.9"

services:

  foo-api:
    image: wiremock/wiremock:2.32.0
    ports:
      - "8080"
    command:
      - "--global-response-templating"
    volumes:
      - ./wiremock/foo-api:/home/wiremock

  bar-api:
    image: wiremock/wiremock:2.32.0
    ports:
      - "8080"
    command:
      - "--global-response-templating"
    volumes:
      - ./wiremock/bar-api:/home/wiremock

进入全屏模式 退出全屏模式

  • 我们使用动态端口。

  • 我们启用响应模板添加参数--global-response-templating(请参阅命令行选项)。

  • 包含 WireMock 映射的目录作为卷安装。

使用 Testcontainers 进行应用测试

静态存根

在Testcontainers JUnit5 扩展的帮助下,我们首先测试已经配置的静态存根:

@Testcontainers
@TestInstance(PER_CLASS)
class AppShouldWithWireMockDocker {

 companion object {
  private const val name = "Ivy" 
  private const val fooServiceName = "foo-api"
  private const val fooServicePort = 8080
  private const val barServiceName = "bar-api"
  private const val barServicePort = 8080
  private lateinit var fooApiHost: String
  private var fooApiPort: Int = 0
  private lateinit var barApiHost: String
  private var barApiPort: Int = 0

  @Container
  @JvmStatic
  val container = DockerComposeContainer<Nothing>(File("docker-compose.yml"))
   .apply {
    withLocalCompose(true)
    withExposedService(fooServiceName, fooServicePort, forListeningPort())
    withExposedService(barServiceName, barServicePort, forListeningPort())
    withLogConsumer()
   }

  @BeforeAll
  @JvmStatic
  fun beforeAll() {
    fooApiHost = container.getServiceHost(fooServiceName, fooServicePort)
    fooApiPort = container.getServicePort(fooServiceName, fooServicePort)
    barApiHost = container.getServiceHost(barServiceName, barServicePort)
    barApiPort = container.getServicePort(barServiceName, barServicePort)
  }
 }

 @Test
 fun `call foo and bar`() {
  val fooApiUrl = "http://${fooApiHost}:${fooApiPort}"
  val barApiUrl = "http://${barApiHost}:${barApiPort}"

  val app = App(name, fooApiUrl, barApiUrl)

  assertThat(app.execute()).isEqualTo(
   """
    Hi! I am $name
    I called Foo and its response is Hello $name I am Foo!
    I called Bar and its response is Hello $name I am Bar!
    Bye!
   """.trimIndent()
  )
 }
}

进入全屏模式 退出全屏模式

  • 我们获取已经分配给每个容器的动态端口来构建fooApiUrlbarApiUrl

动态存根

我们还可以使用WireMock 客户端以编程方式配置我们的存根,并将其连接到两个 WireMock 容器的WireMock Admin API:

@Test
fun `call foo an bar with dynamic stubs`() {
 val fooApiUrl = "http://${fooApiHost}:${fooApiPort}/dynamic"
 val barApiUrl = "http://${barApiHost}:${barApiPort}/dynamic"

 WireMock(fooApiHost, fooApiPort)
  .register(get(urlPathEqualTo("/dynamic/foo"))
   .withQueryParam("name", WireMock.equalTo(name))
   .willReturn(ok().withBody("Hi $name I am Foo, how are you?"))
 )
 WireMock(barApiHost, barApiPort)
  .register(get(urlPathMatching("/dynamic/bar/$name"))
   .willReturn(ok().withBody("Hi $name I am Bar, nice to meet you!"))
 )

 val app = App(name, fooApiUrl, barApiUrl)
 assertThat(app.execute()).isEqualTo(
   """
     Hi! I am $name
     I called Foo and its response is Hi $name I am Foo, how are you?
     I called Bar and its response is Hi $name I am Bar, nice to meet you!
     Bye!
   """.trimIndent()
 )
}

进入全屏模式 退出全屏模式

使用 Docker Compose 运行的应用程序

我们可以轻松地使用与测试相同的 docker-compose 来启动应用程序并在本地运行/调试它:

[图](https://res.cloudinary.com/practicaldev/image/fetch/s--EqHYGq3t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/7dv8qbjqst5nt8oyj3c1.png)

在这种情况下,我们需要使用固定端口,但我们可以使用docker-compose.override.yml来实现,如下所示:

version: "3.9"

services:

  foo-api:
    ports:
      - "8081:8080"

  bar-api:
    ports:
      - "8082:8080"

进入全屏模式 退出全屏模式

此覆盖仅在我们手动执行docker compose时应用,并且不影响**@Testcontainers**。

这很酷,不是吗? 😎

Ofertas 后端

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐