The Jest Object
The jest
object is automatically in scope within every test file. The methods in the jest
object help create mocks and let you control Jest's overall behavior.
Mock Modules
jest.disableAutomock()
Вимикає автоматичну генерацію імітацій в завантажувачі модулів.
See
automock
section of configuration for more information
Після того, як буде викликаний цей метод, всі виклики require()
будуть повертати реальні версії модулів (замість їх імітацій).
Jest configuration:
{
"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');
});
Зазвичай це буває корисно, коли у вас є сценарій, в якому кількість залежностей, для яких потрібно створити імітації, значно менша, ніж тих, для яких імітації не потрібні. Наприклад, якщо ви пишете тест для модуля, який використовує велику кількість залежностей, що можуть бути класифіковані як "деталі реалізації" модуля, тоді вам, схоже, не потрібно створювати імітації для них усіх.
Examples of dependencies that might be considered "implementation details" are things ranging from language built-ins (e.g. Array.prototype methods) to highly common utility methods (e.g. underscore/lo-dash, array utilities, etc) and entire libraries like React.js.
Повертає об’єкт jest
для створення ланцюжків викликів.
Примітка: цей метод раніше називався autoMockOff
. Коли ви використовуєте babel-jest
, виклики disableAutomock
будуть автоматично спливати до початку блоку коду. Використовуйте autoMockOff
, якщо ви хочете явно заборонити таку поведінку.
jest.enableAutomock()
Вмикає автоматичну генерацію імітацій в завантажувачі модулів.
Повертає об’єкт jest
для створення ланцюжків викликів.
See
automock
section of configuration for more information
Приклад:
// 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
, виклики enableAutomock
будуть автоматично спливати до початку блоку коду. Використовуйте autoMockOn
, якщо ви хочете явно заборонити таку поведінку.
jest.genMockFromModule(moduleName)
На основі заданого модуля, використовує систему автоматичного створення імітацій для створення імітації модуля.
Це корисно, коли ви хочете створити ручну імітацію, яка розширює поведінку автоматично створеної імітації модуля.
Приклад:
// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/genMockFromModule.test.js
const utils = jest.genMockFromModule('../utils').default;
utils.isAuthorized = jest.fn(secret => secret === 'not wizard');
test('implementation created by jest.genMockFromModule', () => {
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized('not wizard')).toEqual(true);
});
This is how genMockFromModule
will mock the following data types:
Функція
Creates a new mock function. The new function has no formal parameters and when called will return undefined
. This functionality also applies to async
functions.
Class
Creates a new class. The interface of the original class is maintained, all of the class member functions and properties will be mocked.
Об'єкт
Creates a new deeply cloned object. The object keys are maintained and their values are mocked.
Array
Creates a new empty array, ignoring the original.
Primitives
Creates a new property with the same primitive value as the original property.
Приклад:
// 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.genMockFromModule('./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'));
});
jest.mock(moduleName, factory, options)
Mocks a module with an auto-mocked version when it is being required. factory
and options
are optional. Наприклад:
// 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.
Другий параметр може бути використаний щоб явно вказати фабричний метод модуля, який буде виконано замість автоматичного створення імітації:
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';
When using the factory
parameter for an ES6 module with a default export, the __esModule: true
property needs to be specified. This property is normally generated by Babel / TypeScript, but here it needs to be set manually. When importing a default export, it's an instruction to import the property named default
from the export object:
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
Третій параметр можу бути використаний для створення віртуальних імітацій - таких, які не існують ніде в системі:
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},
);
Warning: Importing a module in a setup file (as specified by
setupTestFrameworkScriptFile
) will prevent mocking for the module in question, as well as all the modules that it imports.
Модулі, для яких створені імітації з допомогою jest.mock
є імітаціями тільки в межах файлу, в якому було викликано jest.mock
. Another file that imports the module will get the original implementation even if it runs after the test file that mocks the module.
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.unmock(moduleName)
Вказує системі модулів більше не повертати імітацію конкретного модуля з require()
(має повертатися оригінальна версія модуля).
Найпоширеніше використання цього API - вказання модуля, який даний тест повинен протестувати (а отже для цього модуля не повивнна бути створена імітація).
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.doMock(moduleName, factory, options)
When using babel-jest
, calls to mock
will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.
Це може бути корисно, коли ви хочете по-різному імітувати модуль в межах одного і того ж файла з тестами:
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);
});
Using jest.doMock()
with ES6 imports requires additional steps. Follow these if you don't want to use require
in your tests:
- We have to specify the
__esModule: true
property (see thejest.mock()
API for more information). - Static ES6 module imports are hoisted to the top of the file, so instead we have to import them dynamically using
import()
. - Finally, we need an environment which supports dynamic importing. Please see Using Babel for the initial setup. Then add the plugin babel-plugin-dynamic-import-node, or an equivalent, to your Babel config to enable dynamic importing in Node.
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
для створення ланцюжків викликів.
jest.dontMock(moduleName)
Коли ви використовуєте babel-jest
, виклики unmock
будуть автоматично спливати до початку блоку коду. Use this method if you want to explicitly avoid this behavior.
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.setMock(moduleName, moduleExports)
Явно вказує об’єкт-імітацію, який має повернути система модулів для вказаного модуля.
On occasion, there are times where the automatically generated mock the module system would normally provide you isn't adequate enough for your testing needs. Зазвичай в таких випадках вам варто написати ручний мок, який найбільш підходить для запитаного модуля. Однак в екстремально рідкісних випадках навіть ручний мок не підходить для ваших цілей і вам потрібно створити імітацію всередині вашого тесту.
В таких рідкісних сценаріях ви можете використати цей API, щоб в ручну заповнити слот в реєстрі імітацій системи модулів.
Повертає об’єкт jest
для створення ланцюжків викликів.
Примітка. Рекомендується використовувати jest.mock()
замість цього метода. Другий аргумент jest.mock
- це функція, яка повертає імітацію замість очікуваного об’єкта модуля.
jest.requireActual(moduleName)
Returns the actual module instead of a mock, bypassing all checks on whether the module should receive a mock implementation or not.
Приклад:
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
jest.requireMock(moduleName)
Returns a mock module instead of the actual module, bypassing all checks on whether the module should be required normally or not.
jest.resetModules()
Resets the module registry - the cache of all required modules. This is useful to isolate modules where local state might conflict between tests.
Приклад:
const sum1 = require('../sum');
jest.resetModules();
const sum2 = require('../sum');
sum1 === sum2;
// > false (sum1 і sum2 є різними екземплярами модуля "sum".)
Приклад в тесті:
beforeEach(() => {
jest.resetModules();
});
test('works', () => {
const sum = require('../sum');
});
test('works too', () => {
const sum = require('../sum');
// змінна sum – це інша копія модуля "sum" у порівнянні з попереднім тестом.
});
Повертає об’єкт jest
для створення ланцюжків викликів.
Mock functions
jest.fn(implementation)
Returns a new, unused mock function. Optionally takes a mock implementation.
const mockFn = jest.fn();
mockFn();
expect(mockFn).toHaveBeenCalled();
// With a mock implementation:
const returnsTrue = jest.fn(() => true);
console.log(returnsTrue()); // true;
jest.isMockFunction(fn)
Визначає, чи задана функція є імітацією.
jest.spyOn(object, methodName)
Creates a mock function similar to jest.fn
but also tracks calls to object[methodName]
. Returns a Jest mock function.
Примітка: За замовчуванням, jest.spyOn
також викликає метод за яким спостерігає. Це відміна поведінка у порівнянні з більшістю інших тестових бібліотек. Якщо ви очете переписати оригінальну функцію, ви можете використати 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.spyOn(object, methodName, accessType?)
Since Jest 22.1.0+, the jest.spyOn
method takes an optional third argument of accessType
that can be either 'get'
or 'set'
, which proves to be useful when you want to spy on a getter or a setter, respectively.
Приклад:
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 audio = require('./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();
});
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();
});
jest.clearAllMocks()
Clears the mock.calls
and mock.instances
properties of all mocks. Equivalent to calling .mockClear()
on every mocked function.
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.resetAllMocks()
Resets the state of all mocks. Equivalent to calling .mockReset()
on every mocked function.
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.restoreAllMocks()
Скидає всі імітації до їх оригінальних значень. Equivalent to calling .mockRestore()
on every mocked function. Beware that jest.restoreAllMocks()
only works when the mock was created with jest.spyOn
; other mocks will require you to manually restore them.
Mock timers
jest.useFakeTimers()
Вказує Jest використовувати імітовані версії стандартних функцій таймерів (setTimeout
, setInterval
, clearTimeout
, clearInterval
, nextTick
, setImmediate
та clearImmediate
).
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.useRealTimers()
Вказує Jest використовувати реальні версії стандартних функцій таймерів.
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.runAllTicks()
Виконує всі мікрозавдання в черзі (зазвичай створені в Node з допомогою process.nextTick
).
Коли викликається цей метод, всі мікрозавдання, заплановані через process.nextTick
будуть виконані. Додатково, якщо ці мікрозавдання самі планують нові мікрозавдання, вони теж будуть постійно виконуватися поки в черзі не залишиться жодного мікрозавдання.
jest.runAllTimers()
Exhausts both the macro-task queue (i.e., all tasks queued by setTimeout()
, setInterval()
, and setImmediate()
) and the micro-task queue (usually interfaced in node via process.nextTick
).
When this API is called, all pending macro-tasks and micro-tasks will be executed. If those tasks themselves schedule new tasks, those will be continually exhausted until there are no more tasks remaining in the queue.
Це часто буває корисно для синхронного виконання setTimeout’ів впродовж тесту для синхронної перевіки якоїсь поведінки, яка відбувається лише після виконання зворотніх викликів в setTimeout()
або setInterval()
. Перегляньте документацію по імітації таймерів для отримання додаткової інформації.
jest.runAllImmediates()
Виконує всі завдання, заплановані з використанням setImmediate()
.
jest.advanceTimersByTime(msToRun)
renamed in Jest 22.0.0+
Also under the alias: .runTimersToTime()
Виконує лише макрозавдання з черги (заплановані, використовуючи setTimeout()
, setInterval()
та setImmediate()
).
When this API is called, all timers are advanced by msToRun
milliseconds. All pending "macro-tasks" that have been queued via setTimeout()
or setInterval()
, and would be executed within this time frame will be executed. Additionally, if those macro-tasks schedule new macro-tasks that would be executed within the same time frame, those will be executed until there are no more macro-tasks remaining in the queue, that should be run within msToRun
milliseconds.
jest.runOnlyPendingTimers()
Виконує лише ті макрозавдання, які в даний час заплановані (тобто лише завдання, які були поставлені в чергу за допомогою setTimeout()
чи setInterval()
до цього моменту). Якщо будь яке з запланованих макрозавдань запланує нове макрозавдання, ті нові завдання не будуть виконані цим викликом.
Це корисно для сценаріїв, коли модуль, що тестується, викликає setTimeout()
, зворотній виклик якого рекурсивно викликає інший setTimeout()
(що означає, що послідовність таймаутів ніколи не припинеться). У таких сценаріях корисно мати можливість рухатися вперед в часі на один крок за раз.
jest.advanceTimersToNextTimer(steps)
Advances all timers by the needed milliseconds so that only the next timeouts/intervals will run.
Optionally, you can provide steps
, so it will run steps
amount of next timeouts/intervals.
jest.clearAllTimers()
Видаляє всі заплановані таймери.
Це означає, що якщо були заплановані будь-які таймери (але вони ще не бли виконані), то вони будуть очищені і не будуть виконані в майбутньому.
jest.getTimerCount()
Returns the number of fake timers still left to run.
Misc
jest.setTimeout(timeout)
Встановлює таймаут за замовчуванням для тестів і before/after хуків в мілісекундах. This only affects the test file from which this function is called.
Примітка. За замовчуванням таймаут становить 5 секунд, якщо цей метод не був викликаний.
Note: If you want to set the timeout for all test files, a good place to do this is in setupFilesAfterEnv
.
Приклад:
jest.setTimeout(1000); // 1 секунда