在开发和测试中使用 WireMock 模拟 API 服务
在本地开发和测试过程中,您的应用依赖于远程 API 的情况非常常见。网络问题、速率限制甚至 API 提供商的停机都可能阻碍您的进度。这会严重影响您的效率并使测试更具挑战性。这就是 WireMock 发挥作用的地方。
WireMock 是一款开源工具,可帮助开发人员创建模拟服务器来模拟真实 API 的行为,从而为开发和测试提供受控的环境。
假设您同时拥有 API 和前端应用程序,并且您想测试前端如何与 API 交互。使用 WireMock,您可以设置模拟服务器来模拟 API 的响应,从而允许您测试前端行为,而无需依赖实际的 API。当 API 仍在开发中或您想测试不同的场景而不会影响实际 API 时,这尤其有用。WireMock 支持 HTTP 和 HTTPS 协议,并且可以模拟各种响应场景,包括延迟、错误和不同的 HTTP 状态代码。
在本指南中,您将学习如何:
- 使用 Docker 启动 WireMock 容器。
- 在本地开发中使用模拟数据,而无需依赖外部 API。
- 在生产环境中使用实时 API 从 AccuWeather 获取实时天气数据。
使用 Docker 部署 WireMock
官方的 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 响应已在映射目录中为您创建。
通过在克隆的项目目录的根目录下运行以下命令来启动 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 容器并接收模拟的响应
您可能已经注意到,您尝试使用 `http://localhost:5001` 作为 URL,而不是端口 `8080`。这是因为您的 Node.js 应用程序正在端口 `5001` 上运行,并且它将请求路由到侦听端口 `8080` 的 WireMock 容器。
提示
在继续下一步之前,请确保您已停止 Node 应用程序服务。
在生产环境中使用实时 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,您可以创建可靠且一致的测试环境,重现极端情况并加快您的开发工作流程。