test mock-03-wiremock 模拟 HTTP 服务的开源工具 flexible and open source API mocking

拓展阅读

test 之 jmockit-01-overview

jmockit-01-test 之 jmockit 入门使用案例

mockito-01-overview mockito 简介及入门使用

PowerMock

Mock Server

ChaosBlade-01-测试混沌工程平台整体介绍

jvm-sandbox 入门简介

wiremock

WireMock是一个流行的开源工具,用于API模拟测试,每月下载量超过500万次。它可以帮助您创建稳定的测试和开发环境,隔离与不稳定的第三方服务的依赖,并模拟尚不存在的API。

WireMock于2011年由Tom Akehurst作为Java库启动,现在已经涵盖多种编程语言和技术栈。

它可以作为库或客户端包装器在许多语言中运行,也可以作为独立的服务器运行。项目及其生态系统背后有一个庞大的社区。

WireMock支持多种创建模拟API的方法 - 在代码中、通过其REST API、作为JSON文件以及通过记录代理到另一个目标的HTTP流量。

WireMock具有丰富的匹配系统,允许将传入请求的任何部分与复杂和精确的条件进行匹配。

通过基于Handlebars的模板系统,可以动态生成任何复杂度的响应。

最后,由于其众多的扩展点和全面的API,WireMock易于集成到任何工作流程中。

关键特性

WireMock可以在单元测试中运行,也可以作为独立进程或容器运行。

其关键特性包括:

  • 可通过URL、头部和正文内容模式进行HTTP响应存根匹配
  • 支持通过流畅的Java API、JSON文件和HTTP传输的JSON进行配置
  • 存根的录制和回放
  • 请求验证
  • 故障和响应延迟注入
  • 按请求的条件代理
  • 用于请求检查和替换的浏览器代理
  • 具有状态的行为模拟
  • 可扩展性

WireMock生态系统

WireMock具有针对其他语言和测试框架的实现和适配器。它支持多种技术栈的适配器和实现,包括Python、.NET、Golang和Rust。

对于JVM生态系统,有适用于Spring Boot、Quarkus、Kotlin、Testcontainers等的库。

WireMock还可以在Android支持上运行,并即将提供官方的gRPC和GraphQL适配器。

快速入门:使用Java和JUnit 4进行API模拟

在本指南中,我们将使用WireMock和JUnit 4编写API单元测试。

先决条件

  • Java 11或17
  • Maven或Gradle,使用最新版本
  • 一个基于Maven和Gradle的Java项目
  • 一个我们将用作演练场的单元测试文件

将WireMock依赖项添加到您的项目

WireMock通过Maven Central分发,可以通过常见的构建工具的依赖管理包含在您的项目中。

要将标准的WireMock JAR添加为项目依赖项,请将以下依赖项放在构建文件的dependencies部分中。

在我们的测试中,我们还将使用AssertJ来验证响应。为了发送请求,我们将使用Java 11+中可用的嵌入式HTTP客户端。

如果您想添加一个Java 1.8测试,您将需要添加一个外部的HTTP客户端实现,如Apache HttpClient。

xml 复制代码
<dependency>
    <groupId>org.wiremock</groupId>
    <artifactId>wiremock</artifactId>
    <version>3.3.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.24.2</version>
    <scope>test</scope>
</dependency>

添加WireMock规则

WireMock提供了一些JUnit规则来管理服务器的生命周期和设置/拆卸任务。

要使用WireMock的流畅API,请添加以下导入语句:

java 复制代码
import static com.github.tomakehurst.wiremock.client.WireMock.*;

为了在每个测试用例中自动启动和停止WireMock,请将以下内容添加到您的测试类(或其超类):

java 复制代码
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089); // No-args constructor defaults to port 8080

写一个测试

java 复制代码
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

...

@Test
public void exampleTest() {
    // Setup the WireMock mapping stub for the test
    stubFor(post("/my/resource")
        .withHeader("Content-Type", containing("xml"))
        .willReturn(ok()
            .withHeader("Content-Type", "text/xml")
            .withBody("<response>SUCCESS</response>")));

    // Setup HTTP POST request (with HTTP Client embedded in Java 11+)
    final HttpClient client = HttpClient.newBuilder().build();
    final HttpRequest request = HttpRequest.newBuilder()
        .uri(wiremockServer.getRequestURI("/my/resource"))
        .header("Content-Type", "text/xml")
        .POST().build();

    // Send the request and receive the response
    final HttpResponse<String> response =
            client.send(request, HttpResponse.BodyHandlers.ofString());

    // Verify the response (with AssertJ)
    assertThat(response.statusCode()).as("Wrong response status code").isEqualTo(200);
    assertThat(response.body()).as("Wrong response body").contains("<response>SUCCESS</response>");
}

拓展测试类

为了对由规则创建的WireMock服务器的设置有更多的控制,您可以将通过流式构建的Options对象传递给规则的构造函数。

让我们以更改端口号为例:

java 复制代码
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
...

@Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().port(8089).httpsPort(8443));

您可以让WireMock(更准确地说是JVM)选择随机的、空闲的HTTP和HTTPS端口。如果您想要并发运行测试,这是一个很好的选择。

java 复制代码
@Rule
public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicPort().dynamicHttpsPort());

可以用下面的发现对应的端口信息:

java 复制代码
int port = wireMockRule.port();
int httpsPort = wireMockRule.httpsPort();

wiremock 是如何实现 http 服务的模拟的?原理是什么

WireMock实现HTTP服务的模拟的基本原理是拦截和模拟HTTP请求,并根据预定义的规则返回相应的模拟响应。

以下是WireMock的基本原理:

  1. 代理模式: WireMock 可以作为一个代理服务器,拦截客户端发出的HTTP请求。当 WireMock 作为代理运行时,它会监听指定的端口,并将接收到的请求发送到实际的目标服务器。WireMock 在中间拦截这些请求,允许你模拟响应。

  2. Stubbing: 在 WireMock 中,模拟服务的期望行为通过 stub(存根)来定义。一个 stub 定义了一个匹配规则和一个对应的响应。当收到符合匹配规则的请求时,WireMock 将返回预定义的响应,而不是将请求转发到实际的目标服务器。

  3. 匹配规则: WireMock 提供了丰富的匹配规则,可以根据请求的URL、HTTP方法、请求体、查询参数等条件进行匹配。这使得可以精确地定义哪些请求应该由 WireMock 进行模拟响应。

  4. DSL(领域特定语言): WireMock 使用了DSL,即一种特定于领域的语言,用于定义 stubs。DSL 提供了清晰而简洁的语法,使得创建和配置 stubs 变得直观和易读。

  5. 内嵌服务器: 除了代理模式,WireMock 还可以作为一个独立的HTTP服务器运行。在这种情况下,它监听指定的端口并直接处理客户端发出的请求,而不需要实际的目标服务器。

  6. 录制和回放: WireMock 具有录制和回放功能,可以用于记录实际服务的请求和响应,然后将其用作模拟服务的期望行为。这有助于创建与实际服务行为一致的 stubs。

相关推荐
pumpkin845141 小时前
客户端发送http请求进行流量控制
python·网络协议·http
互联网杂货铺2 小时前
基于Selenium+Python的web自动化测试框架(附框架源码+项目实战)
自动化测试·软件测试·python·selenium·测试工具·单元测试·测试用例
杨荧2 小时前
【JAVA毕业设计】基于Vue和SpringBoot的宠物咖啡馆平台
java·开发语言·jvm·vue.js·spring boot·spring cloud·开源
Ling_suu3 小时前
Spring——单元测试
java·spring·单元测试
可可爱爱的你吖3 小时前
webSocket的使用文档
网络·websocket·网络协议
熊明才3 小时前
Ubuntu 22.04.4 LTS + certbot 做自动续签SSL证书(2024-11-14亲测)
数据库·网络协议·ssl
喔喔咿哈哈4 小时前
【手撕 Spring】 -- Bean 的创建以及获取
java·后端·spring·面试·开源·github
写bug的小屁孩5 小时前
websocket身份验证
开发语言·网络·c++·qt·websocket·网络协议·qt6.3
luoganttcc6 小时前
能否推荐开源GPU供学习GPU架构
学习·开源
ai产品老杨6 小时前
部署神经网络时计算图的优化方法
人工智能·深度学习·神经网络·安全·机器学习·开源