昨天介紹完非同步後,今天來介紹如何透過 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/