首頁 > 軟體

前端自動化測試之Jest 進階教學範例

2023-02-16 06:01:55

Jest Mock

mock 非同步方法

export const runCallback = callBack => {
  return callBack();
};

我們對上面的程式碼進行測試:

import { runCallback } from "./demo";
test("測試 runCallback", () => {
  const fn = jest.fn(); // mock函數,捕獲函數的呼叫
  runCallback(fn);
  expect(fn).toBeCalled();
  // expect(runCallback(() => "hello")).toBe("hello");
});

通過 jest.fn 生成的 mock 函數,我們可以列印其 fn.mock,得到以下結果:

  • calls 被呼叫的情況,通過 fn.mock.calls.length 可獲取 mock 函數被呼叫次數,每個陣列裡存放傳遞給 mock 函數的引數
  • instances jest.fn 生成函數的 this 指向
  • invocationCallOrder 傳遞進去函數的執行順序
  • results 函數輸出的結果
// mock函數返回123,results的value變為123
const fn = jest.fn(() => 123); 
// 等價於
fn.mockReturnValue("123");
// 等價於
fn.mockImplementation(() => 123);
// 模擬返回一次函數結果
fn.mockReturnValueOnce("123");
// 等價於
fn.mockImplementationOnce(() => 123);

測試非同步程式碼每次都傳送真實請求,無疑是很慢的,我們可以使用 mock 模擬請求方法

  • 匯出我們的請求方法
// demo.js
import axios from "axios";
export function getData() {
  return axios.get("http://www.dell-lee.com/react/api/demo.json");
}
  • 同級目錄下建一個 **mocks** 的資料夾,建立同名的檔案,此檔案就是模擬請求的檔案

export function fetchData() {
  return Promise.resolve({
    success: true
  });
}
  • 測試用例部分:
// 模擬 request 模組
jest.mock("./request.js"); // 也可以在 jest.config.js 裡面手動設定 automock 為 true
// 取消 mock
// jest.unmock("./demo.js");
import { fetchData } from "./request";
test("測試 fetchData", () => {
  // 此請求實際會請求 __mocks__ 下的 request.js 方法
  return fetchData().then(data => {
    expect(data).toEqual({
      success: true
    });
  });
});

如果我們 request.js 某些方法不需要 mock

const { getNumber } = jest.requireActual("./request.js");

Mock Timers

當我們有如下程式碼需要測試的時候:

export default callback => {
  setTimeout(() => {
    callback();
  }, 3000);
};

測試:

import timer from "./timer";
test("測試 timer", done => {
  timer(() => {
    expect(1).toBe(1);
    done();
  });
});

我們不可能總是等待定時器完才去執行用例,這時候我們要用 Jest 來操作時間!步驟如下:

  • 通過 jest.useFakeTimers() 使用 jest "自制的" 定時器
  • 執行 timer 函數之後,快進時間 3 秒 jest.advanceTimersByTime(3000),這個方法可以呼叫任意次,快進的時間會疊加
  • 這時候我們已經穿梭到了 3 秒後,expect 也能生效了!
import timer from "./timer";
beforeEach(() => {
  jest.useFakeTimers();
});
test("測試 timer", () => {
  // jest.fn() 生成的是一個函數,這個函數能被監聽呼叫過幾次
  const fn = jest.fn();
  timer(fn);
  jest.advanceTimersByTime(3000);
  expect(fn).toHaveBeenCalledTimes(1);
});

Mock 類

  • 當我們只關注類的方法是否被呼叫,而不關心方法呼叫產生的結果時,可以 mock 類

util.js 中定義了 Util

export class Util {
  a() {}
  b() {}
}

useUtil.js 呼叫這個類

import { Util } from "./util";
export function useUtil() {
  let u = new Util();
  u.a();
  u.b();
}

我們需要測試 u.au.b 被呼叫

jest.mock("util.js") 會將 Util、Util.a、Util.b 都 mock 成 jest.fn

jest.mock("util.js"); // mock Util 類
import { Util } from "./util/util";
import { useUtil } from "./util/uesUtil";
test("util 的實體方法被執行了", () => {
  useUtil();
  expect(Util).toHaveBeenCalled();
  expect(Util.mock.instances[0].a).toHaveBeenCalled();
  expect(Util.mock.instances[0].b).toHaveBeenCalled();
});

Snapshot 快照測試

  • 將檔案內容拍照一樣拍下來。下次執行測試用例的時候,如果內容變化,則會報錯

config.js

export const generateConfig = () => {
  return {
    server: "https://localhost",
    port: 8080,
    domain: "localhost"
  };
};

測試用例部分:

import { generateConfig } from "./config";
test("測試 generateConfig", () => {
  // 儲存會生成 __snapshots__ 目錄,記住設定相關內容
  expect(generateConfig()).toMatchSnapshot();
});

改變 config 檔案內容,測試不通過,按 u 可以更新快照

如果有兩個快照改變,我們需要一個個更新,我們可以按 i進入以下介面:

s 先跳過此次測試用例

u 可一個個更新快照內容,使得測試通過

如果我們設定有不斷變化的量:

time: new Date()

我們可以這樣測試,保證 time 是一個 Date 型別即可

test("測試 generateConfig", () => {
  expect(generateConfig()).toMatchSnapshot({
    time: expect.any(Date)
  });
});

我們除了可以成目錄儲存快照內容,還可以生成行內快照,存放本檔案即可

test("測試 generateConfig", () => {
  // 需要安裝prettier
  expect(generateConfig()).toMatchInlineSnapshot();
});

DOM 測試

  • jest 自己模擬了一套 jsDom api ,所以我們能使用 jest 測試 dom

dom.js

export function addDivToBody() {
  const div = document.createElement("div");
  document.body.appendChild(div);
}

測試:

import { addDivToBody } from "./timer";
test("測試 addDivToBody", () => {
  addDivToBody();
  addDivToBody();
  expect(document.body.querySelectorAll("div").length).toBe(2);
});

以上就是前端自動化測試之Jest 進階教學範例的詳細內容,更多關於Jest 前端自動化測試的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com