在开发和测试中使用 WireMock 模拟 API 服务
在本地开发和测试期间,应用程序依赖于远程 API 是很常见的。网络问题、速率限制,甚至 API 提供商的停机都可能阻碍您的进度。这会极大地影响您的工作效率,并使测试更具挑战性。而 WireMock 正好可以解决这些问题。
WireMock 是一款开源工具,可帮助开发人员创建模拟服务器,模拟真实 API 的行为,为开发和测试提供受控环境。
假设您有一个 API 和一个前端应用程序,并且您想测试前端如何与 API 进行交互。使用 WireMock,您可以设置一个模拟服务器来模拟 API 的响应,从而无需依赖实际 API 即可测试前端的行为。这在 API 仍在开发中或您想测试不同场景而又不影响实际 API 时特别有用。WireMock 支持 HTTP 和 HTTPS 协议,并且可以模拟各种响应场景,包括延迟、错误和不同的 HTTP 状态码。
在本指南中,您将学习如何
- 使用 Docker 启动 WireMock 容器。
- 在本地开发中使用模拟数据,而不依赖于外部 API
- 在生产环境中使用 Live API 从 AccuWeather 获取实时天气数据。
将 WireMock 与 Docker 一起使用
WireMock 的官方 Docker 镜像提供了一种便捷的方式来部署和管理 WireMock 实例。WireMock 支持多种 CPU 架构,包括 amd64、armv7 和 armv8,确保与不同设备和平台的兼容性。您可以在WireMock 文档站点上了解有关 WireMock 独立版的更多信息。
前提条件
遵循本操作指南需要以下前提条件
启动 WireMock
通过以下步骤快速演示 WireMock
在本地克隆GitHub 仓库。
$ git clone https://github.com/dockersamples/wiremock-node-docker
导航到
wiremock-endpoint
目录$ cd wiremock-node-docker/
WireMock 作为模拟 API,您的后端将与之通信以检索数据。模拟 API 响应已为您创建在 mappings 目录中。
在克隆的项目根目录运行以下命令来启动 Compose 栈
$ docker compose up -d
片刻之后,应用程序将启动并运行。
您可以通过选择
wiremock-node-docker
容器来查看日志测试模拟 API。
$ curl http://localhost:8080/api/v1/getWeather\?city\=Bengaluru
它将返回以下预设响应和模拟数据
{"city":"Bengaluru","temperature":27.1,"conditions":"Mostly cloudy","forecasts":[{"date":"2024-09-02T07:00:00+05:30","temperature":83,"conditions":"Partly sunny w/ t-storms"},{"date":"2024-09-03T07:00:00+05:30","temperature":83,"conditions":"Thunderstorms"},{"date":"2024-09-04T07:00:00+05:30","temperature":83,"conditions":"Intermittent clouds"},{"date":"2024-09-05T07:00:00+05:30","temperature":82,"conditions":"Dreary"},{"date":"2024-09-06T07:00:00+05:30","temperature":82,"conditions":"Dreary"}]}
使用 WireMock,您可以使用映射文件定义预设响应。对于此请求,模拟数据定义在
wiremock-endpoint/mappings/getWeather/getWeatherBengaluru.json
的 JSON 文件中。有关存根预设响应的更多信息,请参阅WireMock 文档。
在开发中使用 WireMock
现在您已经尝试了 WireMock,让我们在开发和测试中使用它。在此示例中,您将使用一个带有 Node.js 后端的示例应用程序。此应用栈具有以下配置:
- 本地开发环境:Node.js 后端和 WireMock 运行的上下文。
- Node.js 后端:代表处理 HTTP 请求的后端应用程序。
- 外部 AccuWeather API:从中获取实时天气数据的真实 API。
- WireMock:在测试期间模拟 API 响应的模拟服务器。它以 Docker 容器的形式运行。


- 在开发中,Node.js 后端将请求发送到 WireMock,而不是实际的 AccuWeather API。
- 在生产环境中,它直接连接到实时 AccuWeather API 以获取真实数据。
在本地开发中使用模拟数据
让我们设置一个 Node 应用程序,使其将请求发送到 WireMock 容器,而不是实际的 AccuWeather API。
前提条件
- 安装Node.js 和 npm
- 确保 WireMock 容器已启动并运行(参见启动 WireMock)
按照步骤设置一个非容器化的 Node 应用程序
导航到
accuweather-api
目录确保您位于
package.json
文件所在的目录中。设置环境变量。
打开
accuweather-api/
目录下的.env
文件。删除旧条目,并确保它只包含以下一行内容。API_ENDPOINT_BASE=http://localhost:8080
这将告诉您的 Node.js 应用程序使用 WireMock 服务器进行 API 调用。
检查应用程序入口点
- 应用程序的主文件是
index.js
,位于accuweather-api/src/api
目录中。 - 此文件启动
getWeather.js
模块,这对于您的 Node.js 应用程序至关重要。它使用dotenv
包从.env
文件加载环境变量。 - 根据
API_ENDPOINT_BASE
的值,应用程序会将请求路由到 WireMock 服务器 (http://localhost:8080
) 或 AccuWeather API。在此设置中,它使用的是 WireMock 服务器。 - 代码确保只有当应用程序不使用 WireMock 时才需要
ACCUWEATHER_API_KEY
,从而提高了效率并避免了错误。
require("dotenv").config(); const express = require("express"); const axios = require("axios"); const router = express.Router(); const API_ENDPOINT_BASE = process.env.API_ENDPOINT_BASE; const API_KEY = process.env.ACCUWEATHER_API_KEY; console.log('API_ENDPOINT_BASE:', API_ENDPOINT_BASE); // Log after it's defined console.log('ACCUWEATHER_API_KEY is set:', !!API_KEY); // Log boolean instead of actual key if (!API_ENDPOINT_BASE) { throw new Error("API_ENDPOINT_BASE is not defined in environment variables"); } // Only check for API key if not using WireMock if (API_ENDPOINT_BASE !== 'http://localhost:8080' && !API_KEY) { throw new Error("ACCUWEATHER_API_KEY is not defined in environment variables"); } // Function to fetch the location key for the city async function fetchLocationKey(townName) { const { data: locationData } = await axios.get(`${API_ENDPOINT_BASE}/locations/v1/cities/search`, { params: { q: townName, details: false, apikey: API_KEY }, }); return locationData[0]?.Key; }
- 应用程序的主文件是
启动 Node 服务器
在启动 Node 服务器之前,请通过运行
npm install
确保您已经安装了package.json
文件中列出的 Node 包。npm install npm run start
您应该会看到以下输出
> express-api-starter@1.2.0 start > node src/index.js API_ENDPOINT_BASE: http://localhost:8080 .. Listening: http://localhost:5001
输出表明您的 Node 应用程序已成功启动。请保持此终端窗口打开。
测试模拟 API
打开一个新的终端窗口并运行以下命令来测试模拟 API
$ curl "http://localhost:5001/api/v1/getWeather?city=Bengaluru"
您应该会看到以下输出
{"city":"Bengaluru","temperature":27.1,"conditions":"Mostly cloudy","forecasts":[{"date":"2024-09-02T07:00:00+05:30","temperature":83,"conditions":"Partly sunny w/ t-storms"},{"date":"2024-09-03T07:00:00+05:30","temperature":83,"conditions":"Thunderstorms"},{"date":"2024-09-04T07:00:00+05:30","temperature":83,"conditions":"Intermittent clouds"},{"date":"2024-09-05T07:00:00+05:30","temperature":82,"conditions":"Dreary"},{"date":"2024-09-06T07:00:00+05:30","temperature":82,"conditions":"Dreary"}]}%
这表明您的 Node.js 应用程序现在已成功将请求路由到 WireMock 容器并接收到模拟响应
您可能已经注意到,您尝试使用的是 URL
http://localhost:5001
而不是端口8080
。这是因为您的 Node.js 应用程序正在端口5001
上运行,并将请求路由到 WireMock 容器,该容器正在监听端口8080
。提示
在继续下一步之前,请确保您已停止 Node 应用程序服务。
在生产环境中使用 Live API 从 AccuWeather 获取实时天气数据
为了使用实时天气数据增强您的 Node.js 应用程序,您可以无缝集成 AccuWeather API。本指南的这一部分将引导您完成设置非容器化 Node.js 应用程序并直接从 AccuWeather API 获取天气信息的步骤。
创建 AccuWeather API 密钥
在https://developer.accuweather.com/注册一个免费的 AccuWeather 开发者账户。在您的账户中,通过选择顶部导航菜单中的 “MY APPS” 创建一个新的应用程序以获取您的唯一 API 密钥。
AccuWeather API是一个提供实时天气数据和预测的 Web API。开发人员可以使用此 API 将天气信息集成到其应用程序、网站或其他项目中。
切换到
accuweather-api
目录$ cd accuweather-api
使用
.env
文件设置您的 AccuWeather API 密钥提示
为防止冲突,在修改
.env
文件之前,请确保删除任何名为API_ENDPOINT_BASE
或ACCUWEATHER_API_KEY
的现有环境变量。在您的终端上运行以下命令
unset API_ENDPOINT_BASE unset ACCUWEATHER_API_KEY
现在是时候在
.env
文件中设置环境变量了ACCUWEATHER_API_KEY=XXXXXX API_ENDPOINT_BASE=http://dataservice.accuweather.com
请务必使用正确的值填充
ACCUWEATHER_API_KEY
。安装依赖项
运行以下命令安装所需的包
$ npm install
这将安装
package.json
文件中列出的所有包。这些包对于项目正常运行至关重要。如果您遇到与已弃用包相关的任何警告,在此演示中可以暂时忽略它们。
假设您的系统上没有预先存在的 Node 服务器正在运行,请继续通过运行以下命令启动 Node 服务器
$ npm run start
您应该会看到以下输出
> express-api-starter@1.2.0 start > node src/index.js API_ENDPOINT_BASE: http://dataservice.accuweather.com ACCUWEATHER_API_KEY is set: true Listening: http://localhost:5001
保持此终端窗口打开。
运行 curl 命令向服务器 URL 发送 GET 请求。
在新的终端窗口中,输入以下命令
$ curl "http://localhost:5000/api/v1/getWeather?city=Bengaluru"
通过运行该命令,您实际上是在告诉本地服务器提供名为
Bengaluru
的城市的天气数据。该请求专门针对/api/v1/getWeather
端点,并且您提供了查询参数city=Bengaluru
。执行命令后,服务器会处理此请求,获取数据并将其作为响应返回,curl
将在您的终端中显示该响应。从外部 AccuWeather API 获取数据时,您正在与反映最新天气状况的实时数据进行交互。
总结
本指南已引导您完成了使用 Docker 设置 WireMock 的过程。您已了解如何创建存根以模拟 API 端点,从而使您无需依赖外部服务即可开发和测试应用程序。通过使用 WireMock,您可以创建可靠且一致的测试环境,重现边缘情况,并加快您的开发工作流程。