該jest對象自動在每個測試文件的范圍內(nèi)。jest對象中的方法有助于創(chuàng)建模擬并讓你控制 Jest 的整體行為。它也可以通過 via 顯式導(dǎo)入?import {jest} from '@jest/globals
?'。
在模塊加載器中禁用自動模擬。
有關(guān)更多信息,請參閱配置automock部分
調(diào)用此方法后,所有require()s 將返回每個模塊的真實版本(而不是模擬版本)。
有配置:
{
"automock": true
}
示例:
// utils.js
export default {
authorize: () => {
return 'token';
},
};
// __tests__/disableAutomocking.js
import utils from '../utils';
jest.disableAutomock();
test('original implementation', () => {
// now we have the original implementation,
// even if we set the automocking in a jest configuration
expect(utils.authorize()).toBe('token');
});
當(dāng)你要模擬的依賴項數(shù)量遠小于你不模擬的依賴項數(shù)量時,這通常很有用。例如,如果你正在為使用大量依賴項的模塊編寫測試,這些依賴項可以合理地歸類為模塊的“實現(xiàn)細節(jié)”,那么你可能不想模擬它們。
可能被視為“實現(xiàn)細節(jié)”的依賴項示例包括從語言內(nèi)置(例如 ?Array.prototype
? 方法)到高度通用的實用程序方法(例如下劃線?/lo-dash
?、數(shù)組實用程序等)和整個庫(如 ?React
?)。 ?js
?。
返回jest用于鏈接的對象。
注意:此方法以前稱為?autoMockOff.
? 使用時?babel-jest
?,對?disableAutomock
?的調(diào)用會自動提升到代碼塊的頂部。使用?autoMockOff
?,如果你想明確地避免這種行為。
在模塊加載器中啟用自動模擬。
返回jest用于鏈接的對象。
有關(guān)更多信息,請參閱配置automock部分
示例:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/enableAutomocking.js
jest.enableAutomock();
import utils from '../utils';
test('original implementation', () => {
// now we have the mocked implementation,
expect(utils.authorize._isMockFunction).toBeTruthy();
expect(utils.isAuthorized._isMockFunction).toBeTruthy();
});
注意:此方法以前稱為?autoMockOn
?. 使用時?babel-jest
?,對 的調(diào)用?enableAutomock
?會自動提升到代碼塊的頂部。使用?autoMockOn
?,如果你想明確地避免這種行為。
同樣在別名下: ?.genMockFromModule(moduleName)
?
給定模塊的名稱,使用自動模擬系統(tǒng)為你生成模塊的模擬版本。
當(dāng)你想要創(chuàng)建擴展自動模擬行為的手動模擬時,這很有用。
示例:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/createMockFromModule.test.js
const utils = jest.createMockFromModule('../utils').default;
utils.isAuthorized = jest.fn(secret => secret === 'not wizard');
test('implementation created by jest.createMockFromModule', () => {
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized('not wizard')).toEqual(true);
});
這是?createMockFromModule
?模擬以下數(shù)據(jù)類型的方式:
創(chuàng)建一個新的模擬函數(shù)。新函數(shù)沒有形式參數(shù),調(diào)用時將返回?undefined
?。此功能也適用于?async
?函數(shù)。
創(chuàng)建一個新類。原始類的接口被保留,所有的類成員函數(shù)和屬性都將被模擬。
創(chuàng)建一個新的深度克隆對象。對象鍵被維護并且它們的值被模擬。
創(chuàng)建一個新的空數(shù)組,忽略原始數(shù)組。
創(chuàng)建一個與原始屬性具有相同原始值的新屬性。
示例:
// example.js
module.exports = {
function: function square(a, b) {
return a * b;
},
asyncFunction: async function asyncSquare(a, b) {
const result = await a * b;
return result;
},
class: new class Bar {
constructor() {
this.array = [1, 2, 3];
}
foo() {}
},
object: {
baz: 'foo',
bar: {
fiz: 1,
buzz: [1, 2, 3],
},
},
array: [1, 2, 3],
number: 123,
string: 'baz',
boolean: true,
symbol: Symbol.for('a.b.c'),
};
// __tests__/example.test.js
const example = jest.createMockFromModule('./example');
test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);
// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);
// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);
// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// creates a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);
// creates a new property with the same primitive value as the original property.
expect(example.number).toEqual(123);
expect(example.string).toEqual('baz');
expect(example.boolean).toEqual(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
在需要時使用自動模擬版本模擬模塊。?factory
?并且?options
?是可選的。例如:
// banana.js
module.exports = () => 'banana';
// __tests__/test.js
jest.mock('../banana');
const banana = require('../banana'); // banana will be explicitly mocked.
banana(); // will return 'undefined' because the function is auto-mocked.
第二個參數(shù)可用于指定正在運行的顯式模塊工廠,而不是使用 Jest 的自動模擬功能:
jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
// This runs the function specified as second argument to `jest.mock`.
const moduleName = require('../moduleName');
moduleName(); // Will return '42';
將?factory
?參數(shù)用于具有默認導(dǎo)出的 ES6 模塊時,?__esModule: true
?需要指定該屬性。該屬性一般由 ?Babel/TypeScript
? 生成,但這里需要手動設(shè)置。導(dǎo)入默認導(dǎo)出時,是導(dǎo)入?default
?從導(dǎo)出對象命名的屬性的指令:
import moduleName, {foo} from '../moduleName';
jest.mock('../moduleName', () => {
return {
__esModule: true,
default: jest.fn(() => 42),
foo: jest.fn(() => 43),
};
});
moduleName(); // Will return 42
foo(); // Will return 43
第三個參數(shù)可用于創(chuàng)建虛擬模擬——系統(tǒng)中不存在的模塊的模擬:
jest.mock(
'../moduleName',
() => {
/*
* Custom implementation of a module that doesn't exist in JS,
* like a generated module or a native module in react-native.
*/
},
{virtual: true},
);
警告:在安裝文件(由 指定?setupTestFrameworkScriptFile
?)中導(dǎo)入模塊將阻止對相關(guān)模塊及其導(dǎo)入的所有模塊進行模擬。
被模擬的模塊jest.mock僅針對調(diào)用jest.mock. 另一個導(dǎo)入模塊的文件將獲得原始實現(xiàn),即使它在模擬模塊的測試文件之后運行。
返回jest用于鏈接的對象。
指示模塊系統(tǒng)不應(yīng)返回指定模塊的模擬版本?require()
?(例如,它應(yīng)始終返回真實模塊)。
此 API 最常見的用途是指定給定測試打算測試的模塊(因此不想自動模擬)。
返回jest用于鏈接的對象。
使用時?babel-jest
?,對 的調(diào)用?mock
?會自動提升到代碼塊的頂部。如果你想明確避免這種行為,請使用此方法。
一個有用的例子是當(dāng)你想在同一個文件中以不同的方式模擬一個模塊時:
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 1);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(1);
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 2);
});
const moduleName = require('../moduleName');
expect(moduleName()).toEqual(2);
});
?jest.doMock()
?與 ES6 導(dǎo)入一起使用需要額外的步驟。如果你不想?require
?在測試中使用,請遵循以下步驟:
__esModule: true屬性
?(jest.mock()有關(guān)更多信息,請參閱API)。
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return {
__esModule: true,
default: 'default1',
foo: 'foo1',
};
});
return import('../moduleName').then(moduleName => {
expect(moduleName.default).toEqual('default1');
expect(moduleName.foo).toEqual('foo1');
});
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return {
__esModule: true,
default: 'default2',
foo: 'foo2',
};
});
return import('../moduleName').then(moduleName => {
expect(moduleName.default).toEqual('default2');
expect(moduleName.foo).toEqual('foo2');
});
});
返回jest用于鏈接的對象。
使用時?babel-jest
?,對 的調(diào)用?unmock
?會自動提升到代碼塊的頂部。如果你想明確避免這種行為,請使用此方法。
返回jest用于鏈接的對象。
顯式提供模塊系統(tǒng)應(yīng)為指定模塊返回的模擬對象。
有時,模塊系統(tǒng)通常為你提供的自動生成的模擬有時不足以滿足你的測試需求。通常在這些情況下,你應(yīng)該編寫一個更適合相關(guān)模塊的手動模擬。但是,在極少數(shù)情況下,即使是手動模擬也不適合你的目的,你需要在測試中自己構(gòu)建模擬。
在這些罕見的情況下,你可以使用此 API 手動填充模塊系統(tǒng)的模擬模塊注冊表中的插槽。
返回jest用于鏈接的對象。
注意 建議jest.mock()改用。該jest.mockAPI的第二個參數(shù)是一個模塊工廠,而不是預(yù)期輸出模塊對象。
返回實際模塊而不是模擬,繞過對模塊是否應(yīng)接收模擬實現(xiàn)的所有檢查。
示例:
jest.mock('../myModule', () => {
// Require the original module to not be mocked...
const originalModule = jest.requireActual('../myModule');
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
getRandom: jest.fn().mockReturnValue(10),
};
});
const getRandom = require('../myModule').getRandom;
getRandom(); // Always returns 10
返回一個模擬模塊而不是實際模塊,繞過對模塊是否應(yīng)該正常需要的所有檢查。
重置模塊注冊表 - 所有必需模塊的緩存。這對于隔離本地狀態(tài)可能在測試之間發(fā)生沖突的模塊很有用。
示例:
const sum1 = require('../sum');
jest.resetModules();
const sum2 = require('../sum');
sum1 === sum2;
// > false (Both sum modules are separate "instances" of the sum module.)
測試中的示例:
beforeEach(() => {
jest.resetModules();
});
test('works', () => {
const sum = require('../sum');
});
test('works too', () => {
const sum = require('../sum');
// sum is a different copy of the sum module from the previous test.
});
返回jest用于鏈接的對象。
?jest.isolateModules(fn)
?比?jest.resetModules()
?為回調(diào)函數(shù)中加載的模塊創(chuàng)建沙箱注冊表更進一步。這對于隔離每個測試的特定模塊非常有用,這樣本地模塊狀態(tài)就不會在測試之間發(fā)生沖突。
let myModule;
jest.isolateModules(() => {
myModule = require('myModule');
});
const otherCopyOfMyModule = require('myModule');
返回一個新的、未使用的模擬函數(shù)??蛇x地采用模擬實現(xiàn)。
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
// With a mock implementation:
const returnsTrue = jest.fn(() => true);
console.log(returnsTrue()); // true;
確定給定的函數(shù)是否是模擬函數(shù)。
創(chuàng)建一個類似于?jest.fn
?但也跟蹤對 的調(diào)用的模擬函數(shù)?object[methodName]
?。返回一個 Jest模擬函數(shù)。
注意:默認情況下,?jest.spyOn
?也會調(diào)用?spied
?方法。這是與大多數(shù)其他測試庫不同的行為。如果你想覆蓋原來的功能,你可以使用?jest.spyOn(object, methodName).mockImplementation(() => customImplementation)
?或?object[methodName] = jest.fn(() => customImplementation);
?
示例:
const video = {
play() {
return true;
},
};
module.exports = video;
示例測試:
const video = require('./video');
test('plays video', () => {
const spy = jest.spyOn(video, 'play');
const isPlaying = video.play();
expect(spy).toHaveBeenCalled();
expect(isPlaying).toBe(true);
spy.mockRestore();
});
從 Jest 22.1.0+ 開始,該?jest.spyOn
?方法采用可選的第三個參數(shù)?accessType
?,可以是?
?或?'get
?'set'
?,這在你想分別監(jiān)視 ?getter
?或 ?setter
?時被證明是有用的。
示例:
const video = {
// it's a getter!
get play() {
return true;
},
};
module.exports = video;
const audio = {
_volume: false,
// it's a setter!
set volume(value) {
this._volume = value;
},
get volume() {
return this._volume;
},
};
module.exports = audio;
示例測試:
const video = require('./video');
test('plays video', () => {
const spy = jest.spyOn(video, 'play', 'get'); // we pass 'get'
const isPlaying = video.play;
expect(spy).toHaveBeenCalled();
expect(isPlaying).toBe(true);
spy.mockRestore();
});
const audio = require('./audio');
test('plays audio', () => {
const spy = jest.spyOn(audio, 'volume', 'set'); // we pass 'set'
audio.volume = 100;
expect(spy).toHaveBeenCalled();
expect(audio.volume).toBe(100);
spy.mockRestore();
});
清除所有模擬的mock.calls和mock.instances屬性。相當(dāng)于調(diào)用.mockClear()每個模擬函數(shù)。
返回jest用于鏈接的對象。
重置所有模擬的狀態(tài)。相當(dāng)于調(diào)用.mockReset()每個模擬函數(shù)。
返回jest用于鏈接的對象。
將所有模擬恢復(fù)到其原始值。相當(dāng)于調(diào)用.mockRestore()每個模擬函數(shù)。請注意,jest.restoreAllMocks()只有在使用jest.spyOn;創(chuàng)建模擬時才有效;其他模擬將要求你手動恢復(fù)它們。
指示玩笑使用的標(biāo)準(zhǔn)定時器功能假版本(setTimeout,setInterval,clearTimeout,clearInterval,nextTick,setImmediate和clearImmediate)。
如果你'modern'作為參數(shù)傳遞,@sinonjs/fake-timers將用作實現(xiàn)而不是 Jest 自己的假計時器。這也模擬了額外的計時器,如Date. 'modern'將是 Jest 27 中的默認行為。
返回jest用于鏈接的對象。
指示 Jest 使用標(biāo)準(zhǔn)計時器函數(shù)的真實版本。
返回jest用于鏈接的對象。
廢氣的微-task隊列(通常在節(jié)點經(jīng)由接口?process.nextTick
?)。
調(diào)用此 API 時,所有已通過排隊的待處理微任務(wù)process.nextTick將被執(zhí)行。此外,如果這些微任務(wù)自己調(diào)度新的微任務(wù),這些微任務(wù)將不斷耗盡,直到隊列中沒有更多的微任務(wù)。
廢氣兩者宏-task隊列(即,所有的任務(wù)排隊通過setTimeout(),setInterval()和setImmediate())和微-task隊列(通常在節(jié)點經(jīng)由接口?process.nextTick
?)。
調(diào)用此 API 時,將執(zhí)行所有未決的宏任務(wù)和微任務(wù)。如果這些任務(wù)自己安排了新任務(wù),那么這些任務(wù)將不斷耗盡,直到隊列中沒有剩余任務(wù)為止。
這對于在測試期間同步執(zhí)行 setTimeouts 通常很有用,以便同步斷言某些僅在執(zhí)行?setTimeout()
?或?setInterval()
?回調(diào)后才會發(fā)生的行為。有關(guān)更多信息,請參閱計時器模擬文檔。
耗盡排隊的所有任務(wù)?setImmediate()
?。
注意:使用現(xiàn)代偽定時器實現(xiàn)時,此功能不可用
同樣在別名下: .runTimersToTime()
只執(zhí)行宏任務(wù)隊列(即所有由?setTimeout()orsetInterval()
?和排隊的任務(wù)?setImmediate()
?)。
調(diào)用此 API 時,所有計時器都會提前?msToRun
?幾毫秒。所有已通過?setTimeout()
?或排隊?setInterval()
?并在此時間范圍內(nèi)執(zhí)行的未決“宏任務(wù)”都將被執(zhí)行。此外,如果這些宏任務(wù)調(diào)度將在同一時間范圍內(nèi)執(zhí)行的新宏任務(wù),則這些宏任務(wù)將被執(zhí)行,直到隊列中沒有更多宏任務(wù)剩余,這應(yīng)該在?msToRun
?幾毫秒內(nèi)運行。
僅執(zhí)行當(dāng)前掛起的宏任務(wù)(即,僅執(zhí)行已排隊?setTimeout()
?或?setInterval()
?到此為止的任務(wù))。如果任何當(dāng)前掛起的宏任務(wù)調(diào)度新的宏任務(wù),則該調(diào)用將不會執(zhí)行這些新任務(wù)。
這對于諸如被測試模塊調(diào)度 ?asetTimeout()
?其回調(diào)以?setTimeout()
?遞歸方式調(diào)度另一個(意味著調(diào)度永不停止)的場景很有用。在這些情況下,能夠一次一步向前運行是很有用的。
將所有計時器提前所需的毫秒數(shù),以便僅運行下一個超時/間隔。
或者,你可以提供steps,因此它將運行steps下一次超時/間隔的數(shù)量。
從計時器系統(tǒng)中刪除任何掛起的計時器。
這意味著,如果任何計時器已被調(diào)度(但尚未執(zhí)行),它們將被清除并且將來永遠沒有機會執(zhí)行。
返回仍要運行的假計時器的數(shù)量。
設(shè)置假定時器使用的當(dāng)前系統(tǒng)時間。模擬用戶在程序運行時更改系統(tǒng)時鐘。它會影響當(dāng)前時間,但它本身不會導(dǎo)致例如定時器觸發(fā);他們將完全按照沒有調(diào)用?jest.setSystemTime()
?.
注意:此功能僅在使用現(xiàn)代偽計時器實現(xiàn)時可用
當(dāng)?mocking
?的時候,??
?也會被?Date.now()
?mock
? 。如果你出于某種原因需要訪問實時當(dāng)前時間,你可以調(diào)用此函數(shù)。
注意:此功能僅在使用現(xiàn)代偽計時器實現(xiàn)時可用
以毫秒為單位設(shè)置測試和掛鉤之前/之后的默認超時間隔。這僅影響調(diào)用此函數(shù)的測試文件。
注意:如果不調(diào)用此方法,默認超時間隔為 5 秒。
注意:如果你想為所有測試文件設(shè)置超時,一個很好的地方是在?setupFilesAfterEnv
?.
示例:
jest.setTimeout(1000); // 1 second
運行失敗的測試 n 次,直到它們通過或直到用盡最大重試次數(shù)。這只適用于jest-circus!
測試中的示例:
jest.retryTimes(3);
test('will fail', () => {
expect(true).toBe(false);
});
返回jest用于鏈接的對象。
更多建議: