亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

使用Jest測試JavaScript(Mock篇)

YorkChen / 1207人閱讀

摘要:測試調(diào)用斷言的執(zhí)行后返回?cái)嘌员徽{(diào)用斷言被調(diào)用了一次斷言傳入的參數(shù)為所創(chuàng)建的函數(shù)還可以設(shè)置返回值,定義內(nèi)部實(shí)現(xiàn)或返回對象。

在本篇教程中,我們會介紹 Jest 中的三個(gè)與 Mock 函數(shù)相關(guān)的API,分別是jest.fn()、jest.spyOn()jest.mock()。使用它們創(chuàng)建Mock函數(shù)能夠幫助我們更好的測試項(xiàng)目中一些邏輯較復(fù)雜的代碼,例如測試函數(shù)的嵌套調(diào)用,回調(diào)函數(shù)的調(diào)用等。

如果你還不知道Jest的基本使用方法,請先閱讀: 《使用Jest測試JavaScript (入門篇)》
為什么要使用Mock函數(shù)?

在項(xiàng)目中,一個(gè)模塊的方法內(nèi)常常會去調(diào)用另外一個(gè)模塊的方法。在單元測試中,我們可能并不需要關(guān)心內(nèi)部調(diào)用的方法的執(zhí)行過程和結(jié)果,只想知道它是否被正確調(diào)用即可,甚至?xí)付ㄔ摵瘮?shù)的返回值。此時(shí),使用Mock函數(shù)是十分有必要。

Mock函數(shù)提供的以下三種特性,在我們寫測試代碼時(shí)十分有用:

捕獲函數(shù)調(diào)用情況

設(shè)置函數(shù)返回值

改變函數(shù)的內(nèi)部實(shí)現(xiàn)

我們接著使用上篇文章中的目錄結(jié)構(gòu),在test/functions.test.js文件中編寫測試代碼,src/目錄下寫被測試代碼。
1. jest.fn()

jest.fn()是創(chuàng)建Mock函數(shù)最簡單的方式,如果沒有定義函數(shù)內(nèi)部的實(shí)現(xiàn),jest.fn()會返回undefined作為返回值。

// functions.test.js

test("測試jest.fn()調(diào)用", () => {
  let mockFn = jest.fn();
  let result = mockFn(1, 2, 3);

  // 斷言mockFn的執(zhí)行后返回undefined
  expect(result).toBeUndefined();
  // 斷言mockFn被調(diào)用
  expect(mockFn).toBeCalled();
  // 斷言mockFn被調(diào)用了一次
  expect(mockFn).toBeCalledTimes(1);
  // 斷言mockFn傳入的參數(shù)為1, 2, 3
  expect(mockFn).toHaveBeenCalledWith(1, 2, 3);
})

jest.fn()所創(chuàng)建的Mock函數(shù)還可以設(shè)置返回值,定義內(nèi)部實(shí)現(xiàn)返回Promise對象

// functions.test.js

test("測試jest.fn()返回固定值", () => {
  let mockFn = jest.fn().mockReturnValue("default");
  // 斷言mockFn執(zhí)行后返回值為default
  expect(mockFn()).toBe("default");
})

test("測試jest.fn()內(nèi)部實(shí)現(xiàn)", () => {
  let mockFn = jest.fn((num1, num2) => {
    return num1 * num2;
  })
  // 斷言mockFn執(zhí)行后返回100
  expect(mockFn(10, 10)).toBe(100);
})

test("測試jest.fn()返回Promise", async () => {
  let mockFn = jest.fn().mockResolvedValue("default");
  let result = await mockFn();
  // 斷言mockFn通過await關(guān)鍵字執(zhí)行后返回值為default
  expect(result).toBe("default");
  // 斷言mockFn調(diào)用后返回的是Promise對象
  expect(Object.prototype.toString.call(mockFn())).toBe("[object Promise]");
})

上面的代碼是jest.fn()提供的幾個(gè)常用的API和斷言語句,下面我們在src/fetch.js文件中寫一些被測試代碼,以更加接近業(yè)務(wù)的方式來理解Mock函數(shù)的實(shí)際應(yīng)用。

被測試代碼中依賴了axios這個(gè)常用的請求庫和JSONPlaceholder這個(gè)上篇文章中提到免費(fèi)的請求接口,請先在shell中執(zhí)行npm install axios --save安裝依賴,。
// fetch.js

import axios from "axios";

export default {
  async fetchPostsList(callback) {
    return axios.get("https://jsonplaceholder.typicode.com/posts").then(res => {
      return callback(res.data);
    })
  }
}

我們在fetch.js中封裝了一個(gè)fetchPostsList方法,該方法請求了JSONPlaceholder提供的接口,并通過傳入的回調(diào)函數(shù)返回處理過的返回值。如果我們想測試該接口能夠被正常請求,只需要捕獲到傳入的回調(diào)函數(shù)能夠被正常的調(diào)用即可。下面是functions.test.js中的測試的代碼。

import fetch from "../src/fetch.js"

test("fetchPostsList中的回調(diào)函數(shù)應(yīng)該能夠被調(diào)用", async () => {
  expect.assertions(1);
  let mockFn = jest.fn();
  await fetch.fetchPostsList(mockFn);

  // 斷言mockFn被調(diào)用
  expect(mockFn).toBeCalled();
})
2. jest.mock()

fetch.js文件夾中封裝的請求方法可能我們在其他模塊被調(diào)用的時(shí)候,并不需要進(jìn)行實(shí)際的請求(請求方法已經(jīng)通過單側(cè)或需要該方法返回非真實(shí)數(shù)據(jù))。此時(shí),使用jest.mock()去mock整個(gè)模塊是十分有必要的。

下面我們在src/fetch.js的同級目錄下創(chuàng)建一個(gè)src/events.js。

// events.js

import fetch from "./fetch";

export default {
  async getPostList() {
    return fetch.fetchPostsList(data => {
      console.log("fetchPostsList be called!");
      // do something
    });
  }
}

functions.test.js中的測試代碼如下:

// functions.test.js

import events from "../src/events";
import fetch from "../src/fetch";

jest.mock("../src/fetch.js");

test("mock 整個(gè) fetch.js模塊", async () => {
  expect.assertions(2);
  await events.getPostList();
  expect(fetch.fetchPostsList).toHaveBeenCalled();
  expect(fetch.fetchPostsList).toHaveBeenCalledTimes(1);
});

在測試代碼中我們使用了jest.mock("../src/fetch.js")去mock整個(gè)fetch.js模塊。如果注釋掉這行代碼,執(zhí)行測試腳本時(shí)會出現(xiàn)以下報(bào)錯(cuò)信息

從這個(gè)報(bào)錯(cuò)中,我們可以總結(jié)出一個(gè)重要的結(jié)論:

在jest中如果想捕獲函數(shù)的調(diào)用情況,則該函數(shù)必須被mock或者spy!
3. jest.spyOn()

jest.spyOn()方法同樣創(chuàng)建一個(gè)mock函數(shù),但是該mock函數(shù)不僅能夠捕獲函數(shù)的調(diào)用情況,還可以正常的執(zhí)行被spy的函數(shù)。實(shí)際上,jest.spyOn()jest.fn()的語法糖,它創(chuàng)建了一個(gè)和被spy的函數(shù)具有相同內(nèi)部代碼的mock函數(shù)。

上圖是之前jest.mock()的示例代碼中的正確執(zhí)行結(jié)果的截圖,從shell腳本中可以看到console.log("fetchPostsList be called!");這行代碼并沒有在shell中被打印,這是因?yàn)橥ㄟ^jest.mock()后,模塊內(nèi)的方法是不會被jest所實(shí)際執(zhí)行的。這時(shí)我們就需要使用jest.spyOn()。

// functions.test.js

import events from "../src/events";
import fetch from "../src/fetch";

test("使用jest.spyOn()監(jiān)控fetch.fetchPostsList被正常調(diào)用", async() => {
  expect.assertions(2);
  const spyFn = jest.spyOn(fetch, "fetchPostsList");
  await events.getPostList();
  expect(spyFn).toHaveBeenCalled();
  expect(spyFn).toHaveBeenCalledTimes(1);
})

執(zhí)行npm run test后,可以看到shell中的打印信息,說明通過jest.spyOn(),fetchPostsList被正常的執(zhí)行了。

4. 總結(jié)

這篇文章中我們介紹了jest.fn(),jest.mock()jest.spyOn()來創(chuàng)建mock函數(shù),通過mock函數(shù)我們可以通過以下三個(gè)特性去更好的編寫我們的測試代碼:

捕獲函數(shù)調(diào)用情況

設(shè)置函數(shù)返回值

改變函數(shù)的內(nèi)部實(shí)現(xiàn)

在實(shí)際項(xiàng)目的單元測試中,jest.fn()常被用來進(jìn)行某些有回調(diào)函數(shù)的測試;jest.mock()可以mock整個(gè)模塊中的方法,當(dāng)某個(gè)模塊已經(jīng)被單元測試100%覆蓋時(shí),使用jest.mock()去mock該模塊,節(jié)約測試時(shí)間和測試的冗余度是十分必要;當(dāng)需要測試某些必須被完整執(zhí)行的方法時(shí),常常需要使用jest.spyOn()。這些都需要開發(fā)者根據(jù)實(shí)際的業(yè)務(wù)代碼靈活選擇。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/98452.html

相關(guān)文章

  • [gist]用 jest 輕松測試 JavaScript

    摘要:的測試不管在用還是都是很頭疼的事情但是自從有了一口氣寫個(gè)測試腰也不疼了頭也不疼了只需要個(gè)理由在說用測為什么好之前我們先來看我們要測的一個(gè)例子栗子比如我要寫一個(gè)模塊要去取用戶的和他所有的數(shù)量那么我們應(yīng)該有一個(gè)的我們還需要一個(gè)的大同小異略去最后 from oyanglul.us Javascript 的測試, 不管在用 jasmine 還是 mocha, 都是很頭疼的事情. 但是自從有了...

    CoderStudy 評論0 收藏0
  • 提高代碼質(zhì)量——使用Jest和Sinon給已有的代碼添加單元測試

    摘要:現(xiàn)在,我們可以使用單元測試來提高自己的代碼質(zhì)量。它在單元測試的編寫中通常用來模擬等相關(guān)請求。通過這篇文章,你應(yīng)該學(xué)會了如何針對已有代碼從零開始編寫一套完整的單元測試用例。 概述 在日常的功能開發(fā)中,我們的代碼測試都依賴于自己或者QA進(jìn)行測試。這些操作不僅費(fèi)時(shí)費(fèi)力,而且還依賴開發(fā)者自身的驅(qū)動。在開發(fā)一些第三方依賴的庫時(shí),我們也沒有辦法給第三方提供完整的代碼質(zhì)量報(bào)告。 現(xiàn)在,我們可以使用單...

    voyagelab 評論0 收藏0
  • React 測試指南

    摘要:單元測試針對程序模塊進(jìn)行測試。是開源的單元測試工具。一個(gè)好的單元測試應(yīng)該具備的條件安全重構(gòu)已有代碼單元測試一個(gè)很重要的價(jià)值是為重構(gòu)保駕護(hù)航。斷言外部依賴單元測試的一個(gè)重要原則就是無依賴和隔離。 前端測試金字塔 對于一個(gè) Web 應(yīng)用來說,理想的測試組合應(yīng)該包含大量單元測試(unit tests),部分快照測試(snapshot tests),以及少量端到端測試(e2e tests)。參...

    Tecode 評論0 收藏0
  • Jest + Enzyme 前端自動化測試

    摘要:簡介是發(fā)布的一個(gè)開源的基于框架的單元測試工具。具體版本對照如下版本版本此處使用的版本為,所以我們需要安裝依賴安裝完成,接下來需要進(jìn)行相關(guān)的配置。這樣就可以將測試集中在組件的結(jié)構(gòu)和邏輯上。 Jest、Enzyme 簡介 Jest 是 Facebook 發(fā)布的一個(gè)開源的、基于 Jasmine 框架的 JavaScript 單元測試工具。 Enzyme 是 React 的測試類庫。 Enzy...

    xushaojieaaa 評論0 收藏0
  • 【全棧React】第23天: 實(shí)現(xiàn)測試

    摘要:包包含由團(tuán)隊(duì)提供的測試實(shí)用程序。將在一個(gè)名為的目錄中自動查找整個(gè)樹中的測試文件是的帶有下劃線。讓我們?yōu)闀r(shí)間軸組件創(chuàng)建第一個(gè)測試。其中之一是命令。現(xiàn)在我們已經(jīng)編寫了第一個(gè)測試并確認(rèn)了我們的設(shè)置我們將在明天開始測試我們的時(shí)間軸組件。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3807原文:https://www.fullstac...

    airborne007 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<