Объект Jest
Объект jest
автоматически создается в глобальной области видимости каждого тестового файла. Методы объекта jest
помогают создать mock-классы/функции/переменные и позволить вам контролировать общее поведение Jest'а. Также он может быть явно импортирован через import {jest} from '@jest/globals'
.
Примеры TypeScript с этой страницы будут работать только в том случае, если вы явно импортируете Jest API:
Import {expect, jest, test} from '@jest/globals';
Обратитесь к Началу работы за подробностями о том, как установить Jest с TypeScript.
Методы
- Mock Модули
jest.disableAutomock()
jest.enableAutomock()
jest.createMockFromModule(moduleName)
jest.mock(moduleName, factory, options)
jest.Mocked<Source>
jest.mocked(source, options?)
jest.unmock(moduleName)
jest.deepUnmock(moduleName)
jest.doMock(moduleName, factory, options)
jest.dontMock(moduleName)
jest.setMock(moduleName, moduleExports)
jest.requireActual(moduleName)
jest.requireMock(moduleName)
jest.resetModules()
jest.isolateModules(fn)
jest.isolateModulesAsync(fn)
- Mock-функции
- Fake Timers
jest.useFakeTimers(fakeTimersConfig?)
jest.useRealTimers()
jest.runAllTicks()
jest.runAllTimers()
jest.runAllTimersAsync()
jest.runAllImmediates()
jest.advanceTimersByTime(msToRun)
jest.advanceTimersByTimeAsync(msToRun)
jest.runOnlyPendingTimers()
jest.runOnlyPendingTimersAsync()
jest.advanceTimersToNextTimer(steps)
jest.advanceTimersToNextTimerAsync(steps)
jest.clearAllTimers()
jest.getTimerCount()
jest.now()
jest.setSystemTime(now?: number | Date)
jest.getRealSystemTime()
- Misc
Mock Модули
jest.disableAutomock()
Отключает автоматическое создание mock-объектов в загрузчике модулей.
Automatic mocking should be enabled via automock
configuration option for this method to have any effect. Also see documentation of the configuration option for more details.
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
automock: true,
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
automock: true,
};
export default config;
After disableAutomock()
is called, all require()
s will return the real versions of each module (rather than a mocked version).
export default {
authorize: () => {
return 'token';
},
};
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
, lodash
, array utilities, etc) and entire libraries like React.js
.
Возвращает объект jest
для создания цепочки вызовов.
When using babel-jest
, calls to disableAutomock()
will automatically be hoisted to the top of the code block. Use autoMockOff()
if you want to explicitly avoid this behavior.
jest.enableAutomock()
Включает автоматическое создание mock-объектов в загрузчике модулей.
For more details on automatic mocking see documentation of automock
configuration option.
Пример:
export default {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
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();
});
Возвращает объект jest
для создания цепочки вызовов.
При использовании babel-jest
вызовы disableAutomock
будут автоматически перенесены наверх в текущем блоке кода. Если вы хотите явно избежать этого поведения, используйте autoMockOff
.
jest.createMockFromModule(moduleName)
Исходя из имени модуля, используйте систему автоматическую имитацию (automocking), чтобы создать для вас мокнутую версию модуля.
This is useful when you want to create a manual mock that extends the automatic mock's behavior:
- JavaScript
- TypeScript
module.exports = {
authorize: () => {
return 'token';
},
isAuthorized: secret => secret === 'wizard',
};
const utils = jest.createMockFromModule('../utils');
utils.isAuthorized = jest.fn(secret => secret === 'not wizard');
test('implementation created by jest.createMockFromModule', () => {
expect(jest.isMockFunction(utils.authorize)).toBe(true);
expect(utils.isAuthorized('not wizard')).toBe(true);
});
export const utils = {
authorize: () => {
return 'token';
},
isAuthorized: (secret: string) => secret === 'wizard',
};
const {utils} =
jest.createMockFromModule<typeof import('../utils')>('../utils');
utils.isAuthorized = jest.fn((secret: string) => secret === 'not wizard');
test('implementation created by jest.createMockFromModule', () => {
expect(jest.isMockFunction(utils.authorize)).toBe(true);
expect(utils.isAuthorized('not wizard')).toBe(true);
});
Это то как можно createMockFromModule
удалить следующие типы данных:
Функция
Creates a new mock function. Новая функция не имеет формальных параметров, и при вызове возвращает undefined
. Эта функция также применима к async
функциям.
Класс
Создает новый класс. Поддерживается интерфейс оригинального класса, все функции и свойства класса будут замоканы.
Объект
Создает новый клонированный объект. Ключи объекта и их значения будут замоканы.
Массив
Создает новый пустой массив, игнорируя оригинал.
Primitives
Создает новое свойство с таким же примитивным значением, как и оригинальное свойство.
Пример:
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'),
};
const example = jest.createMockFromModule('../example');
test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toBe('square');
expect(example.function).toHaveLength(0);
// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toBe('asyncSquare');
expect(example.asyncFunction).toHaveLength(0);
// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toBe('Bar');
expect(example.class.foo.name).toBe('foo');
expect(example.class.array).toHaveLength(0);
// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// создает пустой массив, игнорирую оригинал.
expect(example.array).toHaveLength(0);
// creates a new property with the same primitive value as the original property.
expect(example.number).toBe(123);
expect(example.string).toBe('baz');
expect(example.boolean).toBe(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
jest.mock(moduleName, factory, options)
Сохраняет модуль с auto-mocked версией когда это необходимо. factory
и options
являются необязательными. Например:
module.exports = () => 'banana';
jest.mock('../banana');
const banana = require('../banana'); // banana will be explicitly mocked.
banana(); // вернет 'undefined', потому что функция auto-mocked.
Второй аргумент может быть использован для указания явной фабрики модулей, которые запускаются вместо использования automocking Jest:
- JavaScript
- TypeScript
jest.mock('../moduleName', () => {
return jest.fn(() => 42);
});
// Выполняет указанную функцию в качестве второго аргумента `jest.mock`.
const moduleName = require('../moduleName');
moduleName(); // вернется '42';
// The optional type argument provides typings for the module factory
jest.mock<typeof import('../moduleName')>('../moduleName', () => {
return jest.fn(() => 42);
});
// This runs the function specified as second argument to `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},
);
Importing a module in a setup file (as specified by setupFilesAfterEnv
) will prevent mocking for the module in question, as well as all the modules that it imports.
Модули, которые замоканы с помощью jest.mock
, считаются замоканными только для файла, вызывающего jest.mock
. Другой файл, импортирующий модуль, получит оригинальную реализацию, даже если он запускается после тестового файла, который мокает модуль.
Возвращает объект jest
для создания цепочки вызовов.
Writing tests in TypeScript? Use the jest.Mocked
utility type or the jest.mocked()
helper method to have your mocked modules typed.
jest.Mocked<Source>
See TypeScript Usage chapter of Mock Functions page for documentation.
jest.mocked(source, options?)
See TypeScript Usage chapter of Mock Functions page for documentation.
jest.unmock(moduleName)
Указывает, что система модулей никогда не должна возвращать замоканную версию указанного модуля из require()
(например, что он всегда должен возвращать настоящий модуль).
Чаще всего это используется для указания модуля, который данный тест будет исследовать (и таким образом нам не нужно автоматически мокать его).
Возвращает объект jest
для создания цепочки вызовов.
jest.deepUnmock(moduleName)
Indicates that the module system should never return a mocked version of the specified module and its dependencies.
Возвращает объект 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:
- JavaScript
- TypeScript
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 1);
});
const moduleName = require('../moduleName');
expect(moduleName()).toBe(1);
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return jest.fn(() => 2);
});
const moduleName = require('../moduleName');
expect(moduleName()).toBe(2);
});
beforeEach(() => {
jest.resetModules();
});
test('moduleName 1', () => {
// The optional type argument provides typings for the module factory
jest.doMock<typeof import('../moduleName')>('../moduleName', () => {
return jest.fn(() => 1);
});
const moduleName = require('../moduleName');
expect(moduleName()).toBe(1);
});
test('moduleName 2', () => {
jest.doMock<typeof import('../moduleName')>('../moduleName', () => {
return jest.fn(() => 2);
});
const moduleName = require('../moduleName');
expect(moduleName()).toBe(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).toBe('default1');
expect(moduleName.foo).toBe('foo1');
});
});
test('moduleName 2', () => {
jest.doMock('../moduleName', () => {
return {
__esModule: true,
default: 'default2',
foo: 'foo2',
};
});
return import('../moduleName').then(moduleName => {
expect(moduleName.default).toBe('default2');
expect(moduleName.foo).toBe('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
для создания цепочки вызовов.
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.
- JavaScript
- TypeScript
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(() => 10),
};
});
const getRandom = require('../myModule').getRandom;
getRandom(); // Always returns 10
jest.mock('../myModule', () => {
// Require the original module to not be mocked...
const originalModule =
jest.requireActual<typeof import('../myModule')>('../myModule');
return {
__esModule: true, // Use it when dealing with esModules
...originalModule,
getRandom: jest.fn(() => 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.)