使用 WireMock 在開發和測試中模擬 API 服務

在本地開發和測試期間,您的應用程式依賴遠端 API 的情況相當常見。網路問題、速率限制,甚至 API 提供商的停機都可能 halted your progress. 這會顯著降低您的生產力,並使測試更具挑戰性。這就是 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

  1. 在本機複製 GitHub 儲存庫

  • 瀏覽至 wiremock-endpoint 目錄

    WireMock 作為您的後端將與之通訊以擷取資料的模擬 API。mappings 目錄中已為您建立了模擬 API 回應。

  • 在複製的專案目錄的根目錄執行以下命令來啟動 Compose 堆疊

    片刻之後,應用程式將啟動並執行。

    Diagram showing the WireMock container running on Docker Desktop

    您可以透過選擇 wiremock-node-docker 容器來檢查記錄

    Diagram showing the logs of WireMock container running on Docker Desktop
  • 測試模擬 API。

    它將使用模擬資料返回以下預設回應

    使用 WireMock,您可以使用映射檔定義預設回應。對於此請求,模擬資料定義在 JSON 檔案 wiremock-endpoint/mappings/getWeather/getWeatherBengaluru.json 中。

    有關設定預設回應的更多資訊,請參考 WireMock 文件

  • 在開發中使用 WireMock

    現在您已經試用過 WireMock,讓我們在開發和測試中使用它。在本範例中,您將使用一個具有 Node.js 後端的範例應用程式。此應用程式堆疊具有以下設定

    Diagram showing the architecture of WireMock in development

    在本地開發中使用模擬資料

    讓我們設定一個 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 容器並接收模擬的回應。

      您可能已經注意到,您嘗試使用 http://localhost:5001 作為 URL,而不是埠 8080。這是因為您的 Node.js 應用程式正在埠 5001 上運行,並且它將請求路由到正在埠 8080 上監聽的 WireMock 容器。

      提示

      在繼續下一步之前,請確保您已停止 node 應用程式服務。

    在正式環境中使用即時 API 從 AccuWeather 獲取即時天氣資料

    要使用即時天氣數據增強您的 Node.js 應用程式,您可以無縫整合 AccuWeather API。本指南的此部分將引導您完成設定非容器化 Node.js 應用程式並直接從 AccuWeather API 擷取天氣資訊的步驟。

    1. 建立 AccuWeather API 金鑰

      https://developer.accuweather.com/Diagram showing the AccuWeather Dashboard

      AccuWeather API

  • 使用 .env 檔案設定您的 AccuWeather API 金鑰

    提示

    為防止衝突,請確保在修改 .env 檔案之前移除任何名為 API_ENDPOINT_BASEACCUWEATHER_API_KEY 的現有環境變數。

    在您的終端機上執行以下命令

    現在是設定 .env 檔案中的環境變數的時候了

    確保使用正確的值填充 ACCUWEATHER_API_KEY

  • 安裝依賴項

    執行以下命令以安裝所需的套件

    這將安裝 package.json 檔案中列出的所有套件。這些套件對於專案的正常運作至關重要。

    如果您遇到與已棄用套件相關的任何警告,您可以暫時忽略它們以進行此示範。

  • 假設您的系統上沒有預先存在的 Node 伺服器正在運行,請繼續並透過執行以下命令來啟動 Node 伺服器

    您應該會看到以下輸出

    保持此終端機視窗開啟。

  • 執行 curl 命令以將 GET 請求發送到伺服器 URL。

    在新終端機視窗中,輸入以下命令

    透過執行該命令,您實際上是告訴您的本地伺服器為您提供名為 `Bengaluru` 的城市的天氣數據。該請求專門針對 `/api/v1/getWeather` 端點,並且您正在提供查詢參數 `city=Bengaluru`。執行該命令後,伺服器會處理此請求,擷取數據並將其作為響應返回,`curl` 將在您的終端機中顯示該響應。

    從外部 AccuWeather API 擷取數據時,您正在與反映最新天氣狀況的即時數據互動。

  • 摘要

    本指南已引導您完成使用 Docker 設定 WireMock。您已經學會了如何建立 Stub 來模擬 API 端點,從而使您無需依賴外部服務即可開發和測試您的應用程式。透過使用 WireMock,您可以建立可靠且一致的測試環境,重現邊緣案例,並加快您的開發流程。