Перейти к основной части
Version: 27.0

Объект Jest

Объект jest автоматически создается в глобальной области видимости каждого тестового файла. Методы объекта jest помогают создать mock-классы/функции/переменные и позволить вам контролировать общее поведение Jest'а. Также он может быть явно импортирован через import {jest} from '@jest/globals'.

Mock Модули#

jest.disableAutomock()#

Отключает автоматическое создание mock-объектов в загрузчике модулей.

Смотрите automock раздела конфигурации для получения дополнительной информации

После вызова этого метода все обращения к require() будут возвращать реальные версии каждого модуля (а не их mock-версии).

Конфигурация Jest:

{
"automock": true
}

Пример:

// utils.js
export default {
authorize: () => {
return 'token';
},
};
// __tests__/disableAutomocking.js
import utils from '../utils';
jest.disableAutomock();
test('original implementation', () => {
// теперь у нас есть исходная реализация,
// даже если мы установили automocking в jest конфигурации
expect(utils.authorize()).toBe('token');
});

Это обычно полезно, когда у вас есть сценарий, где количество зависимостей, которые вы хотите сымитировать, гораздо меньше, чем количество зависимостей, для которых это не требуется. Например, если вы пишете тест для модуля, который использует большое число зависимостей, которые могут быть расценены, как «детали реализации» модуля, то вы, вероятно, не захотите их имитировать.

Примеры зависимостей, которые могут считаться «деталями реализации», лежат в диапазоне, начиная от встроенных в язык функций (например, метод Array.prototype) и заканчивая более общими служебными методами (underscore/lo-dash, работа с массивами и т.д.) и даже целыми библиотеками, такими как React.js.

Возвращает объект jest для создания цепочки вызовов.

Note: this method was previously called autoMockOn. When using babel-jest, calls to enableAutomock will automatically be hoisted to the top of the code block. Use autoMockOn if you want to explicitly avoid this behavior.

jest.enableAutomock()#

Включает автоматическое создание mock-объектов в загрузчике модулей.

Возвращает объект jest для создания цепочки вызовов.

Смотрите automock раздела конфигурации для получения дополнительной информации

Пример:

// utils.js
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
// __tests__/enableAutomocking.js
jest.enableAutomock();
import utils from '../utils';
test('original implementation', () => {
// теперь у нас есть mock реализация
expect(utils.authorize._isMockFunction).toBeTruthy();
expect(utils.isAuthorized._isMockFunction).toBeTruthy();
});

Примечание: этот метод ранее назывался autoMockOff. При использовании babel-jest вызовы disableAutomock будут автоматически перенесены наверх в текущем блоке кода. Если вы хотите явно избежать этого поведения, используйте autoMockOff.

jest.createMockFromModule(moduleName)#

переименован в Jest 26.0.0+#

Псевдоним: .genMockFromModule(moduleName)

Исходя из имени модуля, используйте систему автоматическую имитацию (automocking), чтобы создать для вас мокнутую версию модуля.

Это полезно, когда вы хотите создать ручной mock, который расширяет автоматическое поведение мока.

Пример:

// 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('реализация созданная jest.createMockFromModule', () => {
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized('not wizard')).toEqual(true);
});

Это то как можно createMockFromModule удалить следующие типы данных:

Функция#

Создает новую mock-функцию. Новая функция не имеет формальных параметров, и при вызове возвращает undefined. Эта функция также применима к async функциям.

Класс#

Создает новый класс. Поддерживается интерфейс оригинального класса, все функции и свойства класса будут замоканы.

Объект#

Создает новый клонированный объект. Ключи объекта и их значения будут замоканы.

Массив#

Создает новый пустой массив, игнорируя оригинал.

Primitives#

Создает новое свойство с таким же примитивным значением, как и оригинальное свойство.

Пример:

// 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', () => {
// создает новую моковую функцию без формальных аргументов.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);
// асинхронные функции обрабатываются также как стандартные синхронные функции.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);
// создает новый класс с тем же интерфейсом, функции и свойства макаются (имитируются).
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);
// создает клонированную версию исходного объекта.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// создает пустой массив, игнорирую оригинал.
expect(example.array.length).toEqual(0);
// создает новое свойство с тем же примитивным значением что и оригинальное свойство.
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)#

Сохраняет модуль с auto-mocked версией когда это необходимо. factory и options являются необязательными. Например:

// banana.js
module.exports = () => 'banana';
// __tests__/test.js
jest.mock('../banana');
const banana = require('../banana'); // banana будет явно замокан.
banana(); // вернет 'undefined', потому что функция auto-mocked.

Второй аргумент может быть использован для указания явной фабрики модулей, которые запускаются вместо использования automocking Jest:

jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
// Выполняет указанную функцию в качестве второго аргумента `jest.mock`.
const moduleName = require('../moduleName');
moduleName(); // вернется '42';

При использовании параметра factory для модуля ES6 с экспортом по умолчанию, необходимо указать свойство __esModule: true. Это свойство обычно генерируется Babel / TypeScript, но здесь оно должно быть установлено явно вручную. При импорте default export воспользуйтесь этой инструкцией для импорта свойства default из экспортируемого объекта:

import moduleName, {foo} from '../moduleName';
jest.mock('../moduleName', () => {
return {
__esModule: true,
default: jest.fn(() => 42),
foo: jest.fn(() => 43),
};
});
moduleName(); // будет возвращено 42
foo(); // будет возвращено 43

Третий аргумент может быть использован для создания виртуальных моков – моков модулей, которые не существуют в системе:

jest.mock(
'../moduleName",
() => {
/*
* Пользовательская реализация модуля который не существует в JS,
* как сгенерированный модуль или встроенный модуль react-native.
*/
},
{virtual: true},
);

Предупреждение: Импорт модуля в установочном файле (как указано setupTestFrameworkScriptFile) не позволит имитировать модуль в вопросе, а также все те модули, которые импортирует этот модуль.

Модули, которые замоканы с помощью jest.mock, считаются замоканными только для файла, вызывающего jest.mock. Другой файл, импортирующий модуль, получит оригинальную реализацию, даже если он запускается после тестового файла, который мокает модуль.

Возвращает объект jest для создания цепочки вызовов.

jest.unmock(moduleName)#

Указывает, что система модулей никогда не должна возвращать замоканную версию указанного модуля из require() (например, что он всегда должен возвращать настоящий модуль).

Чаще всего это используется для указания модуля, который данный тест будет исследовать (и таким образом нам не нужно автоматически мокать его).

Возвращает объект 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.

One example when this is useful is when you want to mock a module differently within the same file:

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 the jest.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)#

When using babel-jest, calls to unmock will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.

Возвращает объект jest для создания цепочки вызовов.

jest.setMock(moduleName, moduleExports)#

Explicitly supplies the mock object that the module system should return for the specified module.

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. Normally under those circumstances you should write a manual mock that is more adequate for the module in question. However, on extremely rare occasions, even a manual mock isn't suitable for your purposes and you need to build the mock yourself inside your test.

In these rare scenarios you can use this API to manually fill the slot in the module system's mock-module registry.

Возвращает объект jest для создания цепочки вызовов.

Note It is recommended to use jest.mock() instead. The jest.mock API's second argument is a module factory instead of the expected exported module object.

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 (Оба модуля sum являются отдельными "экземплярами" модуля sum.)

Пример в тесте:

beforeEach(() => {
jest.resetModules();
});
test('работает', () => {
const sum = require('../sum');
});
test('также работает', () => {
const sum = require('../sum');
// sum это отличная от предыдущего теста копия модуля sum.
});

Возвращает объект jest для создания цепочки вызовов.

jest.isolateModules(fn)#

jest.isolateModules(fn) goes a step further than jest.resetModules() and creates a sandbox registry for the modules that are loaded inside the callback function. This is useful to isolate specific modules for every test so that local module state doesn't conflict between tests.

let myModule;
jest.isolateModules(() => {
myModule = require('myModule');
});
const otherCopyOfMyModule = require('myModule');

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)#

Determines if the given function is a mocked function.

jest.spyOn(object, methodName)#

Creates a mock function similar to jest.fn but also tracks calls to object[methodName]. Returns a Jest mock function.

Note: By default, jest.spyOn also calls the spied method. This is different behavior from most other test libraries. If you want to overwrite the original function, you can use jest.spyOn(object, methodName).mockImplementation(() => customImplementation) or 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()#

Restores all mocks back to their original value. 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(implementation?: 'modern' | 'legacy')#

Instructs Jest to use fake versions of the standard timer functions (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, setImmediate and clearImmediate as well as Date).

If you pass 'legacy' as an argument, Jest's legacy implementation will be used rather than one based on @sinonjs/fake-timers.

Возвращает объект jest для создания цепочки вызовов.

jest.useRealTimers()#

Instructs Jest to use the real versions of the standard timer functions.

Возвращает объект jest для создания цепочки вызовов.

jest.runAllTicks()#

Exhausts the micro-task queue (usually interfaced in node via process.nextTick).

When this API is called, all pending micro-tasks that have been queued via process.nextTick will be executed. Additionally, if those micro-tasks themselves schedule new micro-tasks, those will be continually exhausted until there are no more micro-tasks remaining in the queue.

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.

This is often useful for synchronously executing setTimeouts during a test in order to synchronously assert about some behavior that would only happen after the setTimeout() or setInterval() callbacks executed. See the Timer mocks doc for more information.

jest.runAllImmediates()#

Exhausts all tasks queued by setImmediate().

Note: This function is not available when using modern fake timers implementation

jest.advanceTimersByTime(msToRun)#

Executes only the macro task queue (i.e. all tasks queued by setTimeout() or setInterval() and 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()#

Executes only the macro-tasks that are currently pending (i.e., only the tasks that have been queued by setTimeout() or setInterval() up to this point). If any of the currently pending macro-tasks schedule new macro-tasks, those new tasks will not be executed by this call.

This is useful for scenarios such as one where the module being tested schedules a setTimeout() whose callback schedules another setTimeout() recursively (meaning the scheduling never stops). In these scenarios, it's useful to be able to run forward in time by a single step at a time.

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.

jest.setSystemTime(now?: number | Date)#

Set the current system time used by fake timers. Simulates a user changing the system clock while your program is running. It affects the current time but it does not in itself cause e.g. timers to fire; they will fire exactly as they would have done without the call to jest.setSystemTime().

Note: This function is only available when using modern fake timers implementation

jest.getRealSystemTime()#

When mocking time, Date.now() will also be mocked. If you for some reason need access to the real current time, you can invoke this function.

Note: This function is only available when using modern fake timers implementation

Misc#

jest.setTimeout(timeout)#

Set the default timeout interval for tests and before/after hooks in milliseconds. This only affects the test file from which this function is called.

Note: The default timeout interval is 5 seconds if this method is not called.

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 second

jest.retryTimes()#

Runs failed tests n-times until they pass or until the max number of retries is exhausted. This only works with the default jest-circus runner!

Пример в тесте:

jest.retryTimes(3);
test('will fail', () => {
expect(true).toBe(false);
});

Возвращает объект jest для создания цепочки вызовов.