
昨天介紹完非同步後,今天來介紹如何透過 mock 來模擬第三方套件庫:axios 。
首先來複習透過 Mock 來模擬第三方套件庫能帶來的好處:可以讓測試的焦點更放在個人的程式碼上,拿來模擬 axios ,還可以避免掉每次測試時去呼叫 API!
首先看看 Jest 官方文件的 mock axios 範例:
透過 jest.mock 的方式模擬 axios 後,在使用 axios.get.mockResolvedValue() 方法,回傳值:
import axios from 'axios';
import Users from './users';
jest.mock('axios');
test('should fetch users', () => {
  const users = [{name: 'Bob'}];
  const resp = {data: users};
  axios.get.mockResolvedValue(resp);
  // or you could use the following depending on your use case:
  // axios.get.mockImplementation(() => Promise.resolve(resp))
  return Users.all().then(data => expect(data).toEqual(users));
});
可以將被模擬的 axios 印出來,會發現 axios 已經被 mock 起來了,且底下有很多 mock 的方法供使用:

來實際練習看看吧!
首先,撰寫一個函式 fetchData ,並透過 axios 來呼叫 API 資料後回傳 response 。
import axios from "axios";
const fetchData = async () => {
  const response = await axios.get(
    `https://jsonplaceholder.typicode.com/todos`
  );
  return response;
};
export default fetchData;
在 test 檔要將 axios mock 起來,並測試接收到的資料是否為 mock 的資料:
import fetchData from "./MockAxios";
import axios from "axios";
//將 axios mock 起來
jest.mock("axios");
test("fetch data", async () => {
  // 透過 mockResolvedValue 讓模擬的 axios 取得模擬資料
  const data = { title: "mock axios" };
  axios.get.mockResolvedValue(data);
  const result = await fetchData();
  // 比對透過 fetchData 呼叫 API 拿到的資料,是否有被替換成模擬資料
  expect(result).toEqual(data);
});
透過以上方式就能成功將 axios 模擬起來阻止發送 API 值!
除了上面的方式外也可以透過 axios-mock-adapter 套件來實現該功能:
首先先安裝該套件:
$ npm install axios-mock-adapter --save-dev
接下來參考文件上的範例程式碼:
var axios = require("axios");
var MockAdapter = require("axios-mock-adapter");
// This sets the mock adapter on the default instance
var mock = new MockAdapter(axios);
// Mock any GET request to /users
// arguments for reply are (status, data, headers)
mock.onGet("/users").reply(200, {
  users: [{ id: 1, name: "John Smith" }],
});
axios.get("/users").then(function (response) {
  console.log(response.data);
});
將原先 fetchData 的範例程式碼改寫:
import fetchData from "./MockAxios";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
const mock = new MockAdapter(axios);
test("fetch data", async () => {
  const data = { title: "mock axios" };
  mock.onGet("https://jsonplaceholder.typicode.com/todos").reply(200, data);
  const result = await fetchData();
  expect(result.data).toEqual(data);
});
直接透過 console 印出 fetchData 的 response 時可以看到透過該套件進行測試的回傳值很接近 axios 套件原有的格式:

今天學習透過兩種方式來模擬 axios 進行測試!
https://jestjs.io/docs/mock-functions#mocking-modules
https://blog.jimmydc.com/mock-asynchronous-functions-with-jest/
https://vhudyma-blog.eu/3-ways-to-mock-axios-in-jest/