Об’єкт Jest
Об'єкт jest
автоматично знаходиться в контексті кожного тес тового файлу. Методи в об'єкті jest
допомагають створити імітації та дозволяють контролювати загальну поведінку Jest. Також його можна імпортувати явно через import {jest} from '@jest/globals'
.
Приклади TypeScript з цієї сторінки будуть працювати, як задокументовано, тільки якщо ви явно імпортуєте Jest API:
import {expect, jest, test} from '@jest/globals';
Інструкцію щодо налаштування Jest за допомогою TypeScript можна знайти на сторінці Початок роботи.
Методи
- Mock Modules
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.onGenerateMock(cb)
jest.resetModules()
jest.isolateModules(fn)
jest.isolateModulesAsync(fn)
- Функції-імітації
- Фіктивні таймери
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.advanceTimersToNextFrame()
jest.clearAllTimers()
jest.getTimerCount()
jest.now()
jest.setSystemTime(now?: number | Date)
jest.getRealSystemTime()
- Misc
Mock Modules
jest.disableAutomock()
Вимикає автоматичну генерацію імітацій в завантажувачі модулів.
Аби цей метод працював, автоматичне створення імітацій повинно бути увімкнено за допомогою параметру конфігурації automock
. Більш детальну інформацію шукайте в документації параметру конфігурації.
- 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;
Після того, як буде викликаний disableAutomock()
, всі виклики require()
будуть повертати реальні версії модулів (замість їх імітацій).
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');
});
Зазвичай це буває корисно, коли у вас є сценарій, в якому кількість залежностей, для яких потрібно створити імітації, значно менша, ніж тих, для яких імітації не потрібні. Наприклад, якщо ви пишете тест для модуля, який використовує велику кількість залежностей, що можуть бути класифіковані як "деталі реалізації" модуля, тоді вам, схоже, не потрібно створювати імітації для них усіх.
Приклади залежностей, які можуть бути розцінені як "деталі реалізації", починаються з вбудованих методів мови (такі як методи Array.prototype
) і закінчуються дуже поширеними допоміжними методами (наприклад, underscore
, lodash
, і так далі) чи навіть цілими бібліотеками типу React.js
.
Повертає об’єкт jest
для створення ланцюжків викликів.
Коли ви використовуєте babel-jest
, виклики disableAutomock()
будуть автоматично спливати до початку блоку коду. Використовуйте autoMockOff()
, якщо ви хочете явно заборонити таку поведінку.
jest.enableAutomock()
Вмикає автоматичну генерацію імітацій в завантажувачі модулів.
Докладнішу інформацію про автоматичне створення імітацій шукайте в документації па раметру конфігурації automock
.
Example:
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
, виклики enableAutomock
будуть автоматично спливати до початку блоку коду. Використовуйте autoMockOn
, якщо ви хочете явно заборонити таку поведінку.
jest.createMockFromModule(moduleName)
На основі заданого модуля, використовує систему автоматичного створення імітацій для створення імітації модуля.
Це корисно, коли ви хочете створити ручну імітацію, яка розширює поведінку автоматично створеної імітації модуля:
- 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);
});
This is how createMockFromModule
will mock the following data types:
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.
Object
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:
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', () => {
// створює нову імітовану функцію без аргументів.
expect(example.function.name).toBe('square');
expect(example.function).toHaveLength(0);
// асинхронні функції обробляються аналогічно до стандартних синхронних функцій.
expect(example.asyncFunction.name).toBe('asyncSquare');
expect(example.asyncFunction).toHaveLength(0);
// створює новий клас з таким самим інтерфейсом; функції-члени та властивості імітуються.
expect(example.class.constructor.name).toBe('Bar');
expect(example.class.foo.name).toBe('foo');
expect(example.class.array).toHaveLength(0);
// створює глибокий клон оригінального об'єкта.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});
// creates a new empty array, ignoring the original array.
expect(example.array).toHaveLength(0);
// створює нову властивість з примітивними значеннями оригінального об'єкта.
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)
Mocks a module with an auto-mocked version when it is being required. factory
and options
are optional. Наприклад:
module.exports = () => 'banana';
jest.mock('../banana');
const banana = require('../banana'); // banana will be explicitly mocked.
banana(); // will return 'undefined' because the function is auto-mocked.
Другий параметр може бути використаний щоб явно вказати фабричний метод модуля, який буде виконано замість автоматичного створення імітації:
- JavaScript
- TypeScript
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';
// Необов'зковий аргумент типу надає тип заводському модулю
jest.mock<typeof import('../moduleName')>('../moduleName', () => {
return jest.fn(() => 42);
});
// Це виконає функцію, передану другим аргументом в `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},
);
Імпорт модуля в файл налаштування (вказаний в setupFilesAfterEnv
) буде перешкоджати створенню імітації для нього, як і для всіх модулів, які він імпортує.
Модулі, для яких створені імітації з допомогою 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
для створення ланцюжків викликів.
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()
(має повертатися оригінальна версія модуля).
Найпоширеніше використання цього API - вказання модуля, який даний тест повинен протестувати (а отже для цього модуля не повивнна бути створена імітація).
Повертає об’єкт jest
для створення ланцюжків викликів.
jest.deepUnmock(moduleName)
Вказує, що система модулів не повинна повертати імітацію конкретного модуля та його залежностей.
Повертає об’єкт 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.
Це може бути корисно, коли ви хочете по-різному імітувати модуль в межах одного і того ж файла з тестами:
- 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', () => {
// Необов'зковий аргумент типу надає тип заводському модулю
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:
- Необхідно вказати властивість
__esModule: true
(див.jest.mock()
API для додаткової інформації). - Статичні імпорти модуля ES6 спливають у верхню частину файлу, тож нам потрібно імпортувати їх динамічно за допомогою
import()
. - Також, нам потрібне середовище, яке підтримує динамічні імпорти. Перегляньте Використання Babel для первинного налаштування. Потім додайте плагін babel-plugin-dynamic-import-nodeабо його еквівалент до вашої конфігурації Babel, щоб увімкнути динамічний імпорт в 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');
});
});