在开发和测试中使用 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

  1. 在本地克隆GitHub 仓库

    $ git clone https://github.com/dockersamples/wiremock-node-docker
    
  2. 导航到 wiremock-endpoint 目录

    $ cd wiremock-node-docker/
    

    WireMock 作为模拟 API,您的后端将与之通信以检索数据。模拟 API 响应已为您创建在 mappings 目录中。

  3. 在克隆的项目根目录运行以下命令来启动 Compose 栈

    $ docker compose up -d
    

    片刻之后,应用程序将启动并运行。

    Diagram showing the WireMock container running on Docker Desktop

    您可以通过选择 wiremock-node-docker 容器来查看日志

    Diagram showing the logs of WireMock container running on Docker Desktop
  4. 测试模拟 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 容器的形式运行。
Diagram showing the architecture of WireMock in development
  • 在开发中,Node.js 后端将请求发送到 WireMock,而不是实际的 AccuWeather API。
  • 在生产环境中,它直接连接到实时 AccuWeather API 以获取真实数据。

在本地开发中使用模拟数据

让我们设置一个 Node 应用程序,使其将请求发送到 WireMock 容器,而不是实际的 AccuWeather API。

前提条件

按照步骤设置一个非容器化的 Node 应用程序

  1. 导航到 accuweather-api 目录

    确保您位于 package.json 文件所在的目录中。

  2. 设置环境变量。

    打开 accuweather-api/ 目录下的 .env 文件。删除旧条目,并确保它只包含以下一行内容。

    API_ENDPOINT_BASE=http://localhost:8080

    这将告诉您的 Node.js 应用程序使用 WireMock 服务器进行 API 调用。

  3. 检查应用程序入口点

    • 应用程序的主文件是 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;
    }
  4. 启动 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 应用程序已成功启动。请保持此终端窗口打开。

  5. 测试模拟 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 获取天气信息的步骤。

  1. 创建 AccuWeather API 密钥

    https://developer.accuweather.com/注册一个免费的 AccuWeather 开发者账户。在您的账户中,通过选择顶部导航菜单中的 “MY APPS” 创建一个新的应用程序以获取您的唯一 API 密钥。

    Diagram showing the AccuWeather Dashboard

    AccuWeather API是一个提供实时天气数据和预测的 Web API。开发人员可以使用此 API 将天气信息集成到其应用程序、网站或其他项目中。

  2. 切换到 accuweather-api 目录

    $ cd accuweather-api
    
  3. 使用 .env 文件设置您的 AccuWeather API 密钥

    提示

    为防止冲突,在修改 .env 文件之前,请确保删除任何名为 API_ENDPOINT_BASEACCUWEATHER_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

  4. 安装依赖项

    运行以下命令安装所需的包

    $ npm install
    

    这将安装 package.json 文件中列出的所有包。这些包对于项目正常运行至关重要。

    如果您遇到与已弃用包相关的任何警告,在此演示中可以暂时忽略它们。

  5. 假设您的系统上没有预先存在的 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

    保持此终端窗口打开。

  6. 运行 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,您可以创建可靠且一致的测试环境,重现边缘情况,并加快您的开发工作流程。

页面选项