(八)Jest測試的mock函數


一、為什么需要引入mock?

最常見的回調函數就是ajax請求,返回數據后執行成功或失敗的回調。在Node 環境下,有一個npm 包request, 它可以發送異步請求,返回數據后調用回調函數進行處理,npm i request --save, 安裝一下,然后func.js 修改如下

const request = require('request');
function fetchData(callback) {
  request('https://jsonplaceholder.typicode.com/todos/1', function (error, response, body) {
    callback(body);
  });
}
module.exports = fetchData;

那怎么測試?肯定調用fetchData, 那就先要創建一個回調函數傳給它,因為fetchData獲取到數據后,會調用回調函數,那就可以在回調函數中創建一個斷言,判斷返回的數據是不是和期望的一樣。func.test.js 文件修改為如下測試代碼。

const fetchData = require('./fun');

test('should return data when fetchData request success', () => {
    function callback(data) {
        expect(data).toEqual({
            "userId": 1,
            "id": 1,
            "title": "delectus aut autem",
            "completed": false
        })
    }

    fetchData(callback);
})

執行npm run test 命令,看到pass,但其實並沒有達到預期的效果,在callback 函數中加入console.log(data) 試一試,就知道了。測試文件改變后,jest 會重新跑一遍(開啟了watch),但並沒有打印出data,也就是說callback 函數並沒有被調用。這是為什么,我在這個地方想了好久,主要還是對異步了解的不夠。當執行jest 測試的時候,實際上是node 執行test函數體的代碼,首先看到callback的函數聲明,它聲明函數,然后看到fetchData() ,它就調用這個函數,請求https://jsonplaceholder.typicode.com/todos/1 接口,這個時候,getTodo函數就執行完了。你可能會想,回調函數都沒有執行,這個函數怎么算執行完了呢?回調函數並不是代碼執行的,而是放到node的異步隊列中被執行的。此時我們就必須引入mock函數了。

二、Jest中的Mock Function

(1)、在jest 創建一個Mock 函數最簡單的方法就是調用jest.fn() 方法。創建mock函數來捕獲調用。具體實現如下:

demo.js文件代碼:

export const forEach = (items, callback) =>{
	for (let index = 0; index < items.length; index++) {
		callback(items[index]);
	}
}

對應的測試用例代碼:demo.test.js  

import {forEach} from "./demo";
test('forEach',()=>{
	const mockCallback = jest.fn();
	forEach([0, 1], mockCallback);
	console.log('mockCallback',mockCallback.mock)//為此mock 函數還有一個mock 屬性
	expect(mockCallback.mock.calls.length).toBe(2)
})

實現結果如下:

 

 calls 保存的就是調用狀態,results保存的就是返回值。invocationCallOrder數組表示函數調用順序。instances表示當前的this

(2)、mockReturnValue 和 mockReturnValueOnce 設置函數的返回值。

import {forEach} from "./demo";
test('forEach',()=>{
	const mockCallback = jest.fn();
	mockCallback.mockReturnValueOnce('abs')
	forEach([0, 1], mockCallback);
	console.log('mockCallback',mockCallback.mock)
	expect(mockCallback.mock.calls.length).toBe(2)
})

運行結果如下:

 

 

mockReturnValueOnce 修改成 mockReturnValue之后發現返回的value值都變成abs。mock函數有mockReturnValue(),它的參數就是返回值。不過它不能返回promise. 可以使用mockResolvedValue直接返回promise的值. 對fetchData 進行mock, 然后設置它的mockResolvedValue()

(3)、toHaveBeenCalled(),  toHaveBeenCalledTimes() ,使用起來有點方便了。你可能見過toBeCalled(),  其實,它和toHaveBeenCalled() 功能是一模一樣的,使用哪個都行。使用起來非常方便。

import {forEach} from "./demo";
test('forEach',()=>{
const mockCallback = jest.fn();
mockCallback.mockReturnValueOnce('abs')
forEach([0, 1], mockCallback);
console.log('mockCallback',mockCallback.mock)
//expect(mockCallback.mock.calls.length).toBe(2)
expect(mockCallback).toHaveBeenCalled()
})  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM