Мок-функции
Мок-функции также называют «шпионами», поскольку они позволяют наблюдать за поведением функции, которая вызывается косвенно другим кодом, а не только проверять результат. Создать мок-функцию можно с помощью jest.fn(). Если реализация не указана, при вызове мок-функция вернёт undefined.
Примеры TypeScript с этой страницы будут работать так, как описано, только если вы явно импортируете API Jest:
import {expect, jest, test} from '@jest/globals';
Подробные сведения о настройке Jest с TypeScript см. в руководстве Начало работы.
Методы
-
Справочник
mockFn.getMockImplementation()mockFn.getMockName()mockFn.mock.callsmockFn.mock.resultsmockFn.mock.instancesmockFn.mock.contextsmockFn.mock.lastCallmockFn.mockClear()mockFn.mockReset()mockFn.mockRestore()mockFn.mockImplementation(fn)mockFn.mockImplementationOnce(fn)mockFn.mockName(name)mockFn.mockReturnThis()mockFn.mockReturnValue(value)mockFn.mockReturnValueOnce(value)mockFn.mockResolvedValue(value)mockFn.mockResolvedValueOnce(value)mockFn.mockRejectedValue(value)mockFn.mockRejectedValueOnce(value)mockFn.whenCalledWith(...args)mockFn.withImplementation(fn, callback)
- Заменённые свойства
- Использование TypeScript
Справочник
mockFn.getMockImplementation()
Возвращает текущую реализацию мок-функции, заданную с помощью mockImplementation(). Возвращает undefined, если реализация не задана.
- JavaScript
- TypeScript
const mockFn = jest.fn(); mockFn.getMockImplementation(); // undefined mockFn.mockImplementation(() => 42); mockFn.getMockImplementation(); // () => 42
import {jest} from '@jest/globals';
const mockFn = jest.fn<() => number>();
mockFn.getMockImplementation(); // undefined
mockFn.mockImplementation(() => 42);
mockFn.getMockImplementation(); // () => 42
mockFn.getMockName()
Возвращает строку с именем мока, заданную вызовом .mockName().
mockFn.mock.calls
Массив, содержащий аргументы всех вызовов этой мок-функции. Каждый элемент массива — это массив аргументов, переданных при вызове.
Например: у мок-функции f, вызванной дважды — сначала с аргументами f('arg1', 'arg2'), а затем с аргументами f('arg3', 'arg4'), — массив mock.calls будет выглядеть так:
[ ['arg1', 'arg2'], ['arg3', 'arg4'], ];
mockFn.mock.results
Массив, содержащий результаты всех вызовов этой мок-функции. Каждая запись в этом массиве — объект, содержащий свойство type и свойство value. type может принимать одно из следующих значений:
-
'return'— означает, что вызов завершился обычным возвратом. -
'throw'— означает, что вызов завершился выбросом значения. -
'incomplete'— означает, что вызов ещё не завершился. Это происходит, если результат проверяется внутри самой мок-функции или внутри функции, вызванной мок-функцией.
Свойство value содержит выброшенное или возвращённое значение. value имеет значение undefined, если type === 'incomplete'.
Например: у мок-функции f, вызванной трижды — вернувшей 'result1', выбросившей ошибку, а затем вернувшей 'result2', — массив mock.results будет выглядеть так:
[
{
type: 'return',
value: 'result1',
},
{
type: 'throw',
value: {/* Error instance */},
},
{
type: 'return',
value: 'result2',
},
];
mockFn.mock.instances
Массив, содержащий все экземпляры объектов, созданные этой мок-функцией с помощью new.
Например: если мок-функция была вызвана как конструктор дважды, массив mock.instances будет выглядеть так:
const mockFn = jest.fn(); const a = new mockFn(); const b = new mockFn(); mockFn.mock.instances[0] === a; // true mockFn.mock.instances[1] === b; // true
mockFn.mock.contexts
Массив, содержащий контексты всех вызовов мок-функции.
Контекст — это значение this, получаемое функцией при вызове. Контекст можно задать с помощью Function.prototype.bind, Function.prototype.call или Function.prototype.apply.
Например:
const mockFn = jest.fn();
const boundMockFn = mockFn.bind(thisContext0);
boundMockFn('a', 'b');
mockFn.call(thisContext1, 'a', 'b');
mockFn.apply(thisContext2, ['a', 'b']);
mockFn.mock.contexts[0] === thisContext0; // true
mockFn.mock.contexts[1] === thisContext1; // true
mockFn.mock.contexts[2] === thisContext2; // true
mockFn.mock.lastCall
Массив, содержащий аргументы последнего вызова этой мок-функции. Если функция не вызывалась, будет возвращено undefined.
Например: у мок-функции f, вызванной дважды — сначала с аргументами f('arg1', 'arg2'), а затем с аргументами f('arg3', 'arg4'), — массив mock.lastCall будет выглядеть так:
['arg3', 'arg4'];
mockFn.mockClear()
Удаляет все данные, сохранённые в массивах mockFn.mock.calls, mockFn.mock.instances, mockFn.mock.contexts и mockFn.mock.results. Это часто полезно, когда нужно очистить данные об использовании мока между двумя проверками.
Параметр конфигурации clearMocks позволяет автоматически очищать моки перед каждым тестом.
Имейте в виду, что mockFn.mockClear() заменит mockFn.mock, а не только сбросит значения его свойств! Поэтому не следует присваивать mockFn.mock другим переменным — временным или постоянным, — чтобы избежать обращения к устаревшим данным.
mockFn.mockReset()
Выполняет всё то же, что и mockFn.mockClear(), а также заменяет реализацию мока пустой функцией, возвращающей undefined.
Параметр конфигурации resetMocks позволяет автоматически сбрасывать моки перед каждым тестом.
mockFn.mockRestore()
Выполняет всё то же, что и mockFn.mockReset(), а также восстанавливает исходную (не замоканную) реализацию.
Это полезно, когда в одних тестовых случаях нужно замокать функции, а в других — восстановить исходную реализацию.
Параметр конфигурации restoreMocks позволяет автоматически восстанавливать моки перед каждым тестом.
mockFn.mockRestore() работает только в том случае, если мок создан с помощью jest.spyOn(). Поэтому при ручном присваивании jest.fn() восстановление необходимо выполнять самостоятельно.
mockFn.mockImplementation(fn)
Принимает функцию, которая будет использоваться в качестве реализации мока. Сам мок по-прежнему будет записывать все поступающие вызовы и создаваемые им экземпляры — единственное отличие состоит в том, что при вызове мока также будет выполняться реализация.
jest.fn(implementation) — это сокращённая запись для jest.fn().mockImplementation(implementation).
- JavaScript
- TypeScript
const mockFn = jest.fn(scalar => 42 + scalar); mockFn(0); // 42 mockFn(1); // 43 mockFn.mockImplementation(scalar => 36 + scalar); mockFn(2); // 38 mockFn(3); // 39
import {jest} from '@jest/globals';
const mockFn = jest.fn((scalar: number) => 42 + scalar);
mockFn(0); // 42
mockFn(1); // 43
mockFn.mockImplementation(scalar => 36 + scalar);
mockFn(2); // 38
mockFn(3); // 39
.mockImplementation() также можно использовать для мокирования конструкторов классов:
- JavaScript
- TypeScript
module.exports = class SomeClass {
method(a, b) {}
};
const SomeClass = require('./SomeClass');
jest.mock('./SomeClass'); // this happens automatically with automocking
const mockMethod = jest.fn();
SomeClass.mockImplementation(() => {
return {
method: mockMethod,
};
});
const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method:', mockMethod.mock.calls);
export class SomeClass {
method(a: string, b: string): void {}
}
import {jest} from '@jest/globals';
import {SomeClass} from './SomeClass';
jest.mock('./SomeClass'); // this happens automatically with automocking
const mockMethod = jest.fn<(a: string, b: string) => void>();
jest.mocked(SomeClass).mockImplementation(() => {
return {
method: mockMethod,
};
});
const some = new SomeClass();
some.method('a', 'b');
console.log('Calls to method:', mockMethod.mock.calls);
mockFn.mockImplementationOnce(fn)
Принимает функцию, которая будет использоваться в качестве реализации мока для одного вызова замоканной функции. Вызовы можно объединять в цепочку, чтобы разные вызовы функции возвращали разные результаты.
- JavaScript
- TypeScript
const mockFn = jest .fn() .mockImplementationOnce(cb => cb(null, true)) .mockImplementationOnce(cb => cb(null, false)); mockFn((err, val) => console.log(val)); // true mockFn((err, val) => console.log(val)); // false
import {jest} from '@jest/globals';
const mockFn = jest
.fn<(cb: (a: null, b: boolean) => void) => void>()
.mockImplementationOnce(cb => cb(null, true))
.mockImplementationOnce(cb => cb(null, false));
mockFn((err, val) => console.log(val)); // true
mockFn((err, val) => console.log(val)); // false
Когда у замоканной функции закончатся реализации, заданные с помощью .mockImplementationOnce(), она выполнит реализацию по умолчанию, заданную с помощью jest.fn(() => defaultValue) или .mockImplementation(() => defaultValue), если эти методы вызывались:
const mockFn = jest .fn(() => 'default') .mockImplementationOnce(() => 'first call') .mockImplementationOnce(() => 'second call'); mockFn(); // 'first call' mockFn(); // 'second call' mockFn(); // 'default' mockFn(); // 'default'
mockFn.mockName(name)
Принимает строку, которая будет использоваться в выводе результатов теста вместо 'jest.fn()', чтобы указывать, на какую мок-функцию ссылаются.
Например:
const mockFn = jest.fn().mockName('mockedFunction');
// mockFn();
expect(mockFn).toHaveBeenCalled();
В результате появится такая ошибка:
expect(mockedFunction).toHaveBeenCalled() Expected number of calls: >= 1 Received number of calls: 0
mockFn.mockReturnThis()
Сокращённая запись для:
jest.fn(function () {
return this;
});
mockFn.mockReturnValue(value)
Сокращённая запись для:
jest.fn().mockImplementation(() => value);
Принимает значение, которое будет возвращаться при каждом вызове мок-функции.
- JavaScript
- TypeScript
const mock = jest.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
import {jest} from '@jest/globals';
const mock = jest.fn<() => number>();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockFn.mockReturnValueOnce(value)
Сокращённая запись для:
jest.fn().mockImplementationOnce(() => value);
Принимает значение, которое будет возвращено при одном вызове мок-функции. Вызовы можно объединять в цепочку, чтобы последовательные вызовы мок-функции возвращали разные значения. Когда значения mockReturnValueOnce закончатся, вызовы будут возвращать значение, заданное с помощью mockReturnValue.
- JavaScript
- TypeScript
const mockFn = jest
.fn()
.mockReturnValue('default')
.mockReturnValueOnce('first call')
.mockReturnValueOnce('second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
import {jest} from '@jest/globals';
const mockFn = jest
.fn<() => string>()
.mockReturnValue('default')
.mockReturnValueOnce('first call')
.mockReturnValueOnce('second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'
mockFn.mockResolvedValue(value)
Сокращённая запись для:
jest.fn().mockImplementation(() => Promise.resolve(value));
Полезно для мокирования асинхронных функций в асинхронных тестах:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest.fn().mockResolvedValue(43);
await asyncMock(); // 43
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest.fn<() => Promise<number>>().mockResolvedValue(43);
await asyncMock(); // 43
});
mockFn.mockResolvedValueOnce(value)
Сокращённая запись для:
jest.fn().mockImplementationOnce(() => Promise.resolve(value));
Полезно для возврата разных значений в нескольких асинхронных вызовах:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockResolvedValue('default')
.mockResolvedValueOnce('first call')
.mockResolvedValueOnce('second call');
await asyncMock(); // 'first call'
await asyncMock(); // 'second call'
await asyncMock(); // 'default'
await asyncMock(); // 'default'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<string>>()
.mockResolvedValue('default')
.mockResolvedValueOnce('first call')
.mockResolvedValueOnce('second call');
await asyncMock(); // 'first call'
await asyncMock(); // 'second call'
await asyncMock(); // 'default'
await asyncMock(); // 'default'
});
mockFn.mockRejectedValue(value)
Сокращённая запись для:
jest.fn().mockImplementation(() => Promise.reject(value));
Полезно для создания асинхронных мок-функций, которые всегда завершаются отклонённым промисом:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockRejectedValue(new Error('Async error message'));
await asyncMock(); // throws 'Async error message'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<never>>()
.mockRejectedValue(new Error('Async error message'));
await asyncMock(); // throws 'Async error message'
});
mockFn.mockRejectedValueOnce(value)
Сокращённая запись для:
jest.fn().mockImplementationOnce(() => Promise.reject(value));
Полезно в сочетании с .mockResolvedValueOnce() или для отклонения промиса с разными исключениями в нескольких асинхронных вызовах:
- JavaScript
- TypeScript
test('async test', async () => {
const asyncMock = jest
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error message'));
await asyncMock(); // 'first call'
await asyncMock(); // throws 'Async error message'
});
import {jest, test} from '@jest/globals';
test('async test', async () => {
const asyncMock = jest
.fn<() => Promise<string>>()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error message'));
await asyncMock(); // 'first call'
await asyncMock(); // throws 'Async error message'
});
mockFn.whenCalledWith(...args)
Настраивает возвращаемое значение или реализацию, которые срабатывают только тогда, когда мок вызывается с аргументами, соответствующими ...args. Полезно, когда один мок должен вести себя по-разному для разных списков аргументов, без ветвления логики внутри mockImplementation.
const fn = jest.fn();
fn.whenCalledWith('apple').mockReturnValue('red');
fn.whenCalledWith('banana').mockReturnValue('yellow');
fn('apple'); // 'red'
fn('banana'); // 'yellow'
fn('grape'); // undefined
Возвращаемый объект — это настоящий Mock, поэтому здесь доступны все методы цепочки обычного jest.fn(): mockReturnValue, mockReturnValueOnce, mockResolvedValue, mockResolvedValueOnce, mockRejectedValue, mockRejectedValueOnce, mockImplementation, mockImplementationOnce. Каждый подходящий вызов направляется в соответствующий подмок; вызовы, не соответствующие условиям, передаются базовому моку.
Сопоставление
Каждый элемент args принимает литерал или любой асимметричный матчёр:
fn.whenCalledWith(expect.any(Number)).mockReturnValue('numeric');
fn.whenCalledWith({user: expect.any(String)}).mockReturnValue('user');
fn(42); // 'numeric'
fn({user: 'alice'}); // 'user'
Структурное равенство, различение Map/Set и асимметричные матчёры работают так, как и ожидается от toHaveBeenCalledWith(). Пользовательские тестеры, зарегистрированные через expect.addEqualityTesters(...), пока не применяются при сопоставлении whenCalledWith. Если вам это необходимо, создайте задачу.
-
Арность —
whenCalledWith('a')соответствуетfn('a')иfn('a', undefined), но неfn('a', 'b')илиfn(). (Допускаются завершающиеundefined, чтобы соответствовать существующей семантике отслеживания вызовов Jest.) - Глубокое равенство — объекты, массивы, Map и Set сравниваются структурно.
Несколько матчёров
Разные матчёры направляют вызовы независимо:
const fn = jest.fn();
fn.whenCalledWith('a').mockReturnValue(1);
fn.whenCalledWith('b').mockReturnValue(2);
fn.whenCalledWith('c').mockReturnValue(3);
fn('a'); // 1
fn('b'); // 2
fn('c'); // 3
fn('z'); // undefined
Две регистрации, матчёры которых пересекаются для определённого вызова (например, expect.objectContaining({a: 1}) и expect.objectContaining({b: 2}) для fn({a: 1, b: 2})), обе соответствуют ему. Правила приоритета ниже определяют, какая из них сработает.
Одноразовые и постоянные значения
mockReturnValueOnce добавляет одноразовое значение в очередь соответствующей ветви; mockReturnValue задаёт постоянное значение по умолчанию. Одноразовые значения используются в порядке регистрации, а затем срабатывает постоянное значение:
fn.whenCalledWith('x')
.mockReturnValueOnce('A')
.mockReturnValueOnce('B')
.mockReturnValue('persistent');
fn('x'); // 'A'
fn('x'); // 'B'
fn('x'); // 'persistent'
fn('x'); // 'persistent'
Асинхронные варианты работают так же:
const fetchUser = jest.fn();
fetchUser.whenCalledWith(1).mockResolvedValue({id: 1});
fetchUser.whenCalledWith(2).mockRejectedValue(new Error('not found'));
Повторные вызовы возвращают новые ветви
Каждый вызов whenCalledWith(...) возвращает совершенно новый подмок, даже если матчёры выглядят одинаково. Вызовы с пересекающимися матчёрами разрешаются по приведённым ниже правилам приоритета: преимущество имеет последнее зарегистрированное постоянное значение, а одноразовые значения из очереди используются в порядке регистрации во всех подходящих ветвях:
fn.whenCalledWith('x')
.mockReturnValueOnce('first-once')
.mockReturnValue('first-persistent');
fn.whenCalledWith('x')
.mockReturnValueOnce('second-once')
.mockReturnValue('second-persistent');
fn('x'); // 'first-once' (earliest matching branch's queued once)
fn('x'); // 'second-once' (next branch's queued once)
fn('x'); // 'second-persistent' (last-registered persistent wins after onces drain)
fn('x'); // 'second-persistent'
Передача вызова базовому моку
Когда в подходящей ветви заканчиваются значения (одноразовые значения из очереди использованы, а постоянное значение не задано), вызов передаётся базовому моку — он не возвращает undefined без предупреждения:
fn.mockReturnValue('default');
fn.whenCalledWith('x').mockReturnValueOnce('once');
fn('x'); // 'once'
fn('x'); // 'default' (matched branch drained, falls through)
fn('y'); // 'default' (no matcher fires)
Приоритет
Если одному вызову соответствуют несколько регистраций, они разрешаются в следующем порядке:
| Приоритет | Источник |
|---|---|
| 1 | Очередь базового *Once (fn.mockReturnValueOnce, fn.mockImplementationOnce и т. д.) — наиболее явное переопределение для одного вызова, срабатывающее независимо от совпадающих ветвей |
| 2 | Самая ранняя зарегистрированная подходящая ветвь с *Once
|
| 3 | Самая поздняя зарегистрированная подходящая ветвь с постоянной реализацией |
| 4 | Реализация, заданная для базового мока (fn.mockReturnValue, исходный метод spyOn и т. д.), или undefined, если её нет |
fn.mockReturnValue('base');
fn.whenCalledWith('x').mockReturnValue('matched-persistent');
fn.whenCalledWith('x').mockReturnValueOnce('matched-once');
fn.mockReturnValueOnce('base-once');
fn('x'); // 'base-once' — priority 1
fn('x'); // 'matched-once' — priority 2
fn('x'); // 'matched-persistent' — priority 3
fn('y'); // 'base' — priority 4 (no match)
Для шпионов
Работает с jest.spyOn(). Вызовы, не соответствующие условиям, передаются исходному методу объекта, за которым ведётся наблюдение:
const target = {greet: name => `hello ${name}`};
const spy = jest.spyOn(target, 'greet');
spy.whenCalledWith('world').mockReturnValue('hi world');
target.greet('world'); // 'hi world'
target.greet('jest'); // 'hello jest' (original method)
Сброс
Вызов mockReset() для родительского объекта удаляет все регистрации whenCalledWith и сбрасывает каждый подмок, поэтому все сохранённые ссылки будут отражать состояние после сброса. Вызов mockReset() для подмока очищает только эту ветвь.
fn.whenCalledWith('x').mockReturnValue('X');
fn('x'); // 'X'
fn.mockReset();
fn('x'); // undefined — registration gone
TypeScript
whenCalledWith принимает тот же кортеж матчёров, что и toHaveBeenCalledWith: тип каждого параметра ограничен типом параметра мока, но в соответствующем элементе также допускается асимметричный матчёр. Цепочки вызовов mockReturnValue/mockResolvedValue ограничены типом возвращаемого значения мока:
const fn = jest.fn<(id: number, options?: {strict: boolean}) => string>();
fn.whenCalledWith(1, {strict: true}).mockReturnValue('exact');
fn.whenCalledWith(expect.any(Number)).mockReturnValue('any number');
fn.whenCalledWith(1).mockReturnValue(42); // Type error — return must be string
fn.whenCalledWith('one'); // Type error — first arg must be number
mockFn.withImplementation(fn, callback)
Принимает функцию, которая будет временно использоваться в качестве реализации мока во время выполнения обратного вызова.
test('test', () => {
const mock = jest.fn(() => 'outside callback');
mock.withImplementation(
() => 'inside callback',
() => {
mock(); // 'inside callback'
},
);
mock(); // 'outside callback'
});
mockFn.withImplementation можно использовать независимо от того, является ли обратный вызов асинхронным (возвращает ли он thenable). Если обратный вызов асинхронный, будет возвращён промис. Ожидание этого промиса дождётся завершения обратного вызова и сбросит реализацию.
test('async test', async () => {
const mock = jest.fn(() => 'outside callback');
// We await this call since the callback is async
await mock.withImplementation(
() => 'inside callback',
async () => {
mock(); // 'inside callback'
},
);
mock(); // 'outside callback'
});
Заменённые свойства
replacedProperty.replaceValue(value)
Изменяет значение уже заменённого свойства. Это полезно, когда нужно заменить свойство, а затем настроить его значение в отдельных тестах. В качестве альтернативы можно несколько раз вызвать jest.replaceProperty() для одного и того же свойства.
replacedProperty.restore()
Восстанавливает исходное значение свойства объекта.
Обратите внимание, что replacedProperty.restore() работает только в том случае, если значение свойства было заменено с помощью jest.replaceProperty().
Параметр конфигурации restoreMocks позволяет автоматически восстанавливать заменённые свойства перед каждым тестом.
Использование TypeScript
Примеры TypeScript с этой страницы будут работать так, как описано, только если вы явно импортируете API Jest:
import {expect, jest, test} from '@jest/globals';
Подробные сведения о настройке Jest с TypeScript см. в руководстве Начало работы.
jest.fn(implementation?)
Если передать реализацию в jest.fn(), правильные типы мока будут выведены автоматически. Во многих случаях реализация не указывается. Чтобы обеспечить безопасность типов, можно передать аргумент обобщённого типа (дополнительные примеры см. выше):
import {expect, jest, test} from '@jest/globals';
import type add from './add';
import calculate from './calc';
test('calculate calls add', () => {
// Create a new mock that can be used in place of `add`.
const mockAdd = jest.fn<typeof add>();
// `.mockImplementation()` now can infer that `a` and `b` are `number`
// and that the returned value is a `number`.
mockAdd.mockImplementation((a, b) => {
// Yes, this mock is still adding two numbers but imagine this
// was a complex function we are mocking.
return a + b;
});
// `mockAdd` is properly typed and therefore accepted by anything
// requiring `add`.
calculate(mockAdd, 1, 2);
expect(mockAdd).toHaveBeenCalledTimes(1);
expect(mockAdd).toHaveBeenCalledWith(1, 2);
});
jest.Mock<T>
Создаёт тип мок-функции, например тип возвращаемого значения jest.fn(). Это может быть полезно, если необходимо определить рекурсивную мок-функцию:
import {jest} from '@jest/globals';
const sumRecursively: jest.Mock<(value: number) => number> = jest.fn(value => {
if (value === 0) {
return 0;
} else {
return value + fn(value - 1);
}
});
jest.Mocked<Source>
Вспомогательный тип jest.Mocked<Source> возвращает тип Source, дополненный определениями типов мок-функции Jest.
import {expect, jest, test} from '@jest/globals';
import type {fetch} from 'node-fetch';
jest.mock('node-fetch');
let mockedFetch: jest.Mocked<typeof fetch>;
afterEach(() => {
mockedFetch.mockClear();
});
test('makes correct call', () => {
mockedFetch = getMockedFetch();
// ...
});
test('returns correct data', () => {
mockedFetch = getMockedFetch();
// ...
});
Типы классов, функций или объектов можно передать в качестве аргумента типа для jest.Mocked<Source>. Если вы предпочитаете ограничить входной тип, используйте: jest.MockedClass<Source>, jest.MockedFunction<Source> или jest.MockedObject<Source>.
jest.Replaced<Source>
Вспомогательный тип jest.Replaced<Source> возвращает тип Source, дополненный определениями типов заменённого свойства Jest.
export function isLocalhost(): boolean {
return process.env['HOSTNAME'] === 'localhost';
}
import {afterEach, expect, it, jest} from '@jest/globals';
import {isLocalhost} from '../utils';
let replacedEnv: jest.Replaced<typeof process.env> | undefined = undefined;
afterEach(() => {
replacedEnv?.restore();
});
it('isLocalhost should detect localhost environment', () => {
replacedEnv = jest.replaceProperty(process, 'env', {HOSTNAME: 'localhost'});
expect(isLocalhost()).toBe(true);
});
it('isLocalhost should detect non-localhost environment', () => {
replacedEnv = jest.replaceProperty(process, 'env', {HOSTNAME: 'example.com'});
expect(isLocalhost()).toBe(false);
});
jest.mocked(source, options?)
Вспомогательный метод mocked() оборачивает типы объекта source и его вложенных элементов определениями типов мок-функций Jest. Чтобы отключить глубокое мокирование, передайте {shallow: true} в качестве аргумента options.
Возвращает объект source.
export const song = {
one: {
more: {
time: (t: number) => {
return t;
},
},
},
};
import {expect, jest, test} from '@jest/globals';
import {song} from './song';
jest.mock('./song');
jest.spyOn(console, 'log');
const mockedSong = jest.mocked(song);
// or through `jest.Mocked<Source>`
// const mockedSong = song as jest.Mocked<typeof song>;
test('deep method is typed correctly', () => {
mockedSong.one.more.time.mockReturnValue(12);
expect(mockedSong.one.more.time(10)).toBe(12);
expect(mockedSong.one.more.time.mock.calls).toHaveLength(1);
});
test('direct usage', () => {
jest.mocked(console.log).mockImplementation(() => {
return;
});
console.log('one more time');
expect(jest.mocked(console.log).mock.calls).toHaveLength(1);
});
jest.Spied<Source>
Создаёт тип объекта класса или функции, за которыми ведётся наблюдение (то есть тип возвращаемого значения jest.spyOn()).
import {jest} from '@jest/globals';
export function setDateNow(now: number): jest.Spied<typeof Date.now> {
return jest.spyOn(Date, 'now').mockReturnValue(now);
}
import {afterEach, expect, type jest, test} from '@jest/globals';
import {setDateNow} from './__utils__/setDateNow';
let spiedDateNow: jest.Spied<typeof Date.now> | undefined = undefined;
afterEach(() => {
spiedDateNow?.mockReset();
});
test('renders correctly with a given date', () => {
spiedDateNow = setDateNow(1_482_363_367_071);
// ...
expect(spiedDateNow).toHaveBeenCalledTimes(1);
});
Типы класса или функции можно передать в качестве аргумента типа для jest.Spied<Source>. Если вы предпочитаете ограничить входной тип, используйте jest.SpiedClass<Source> или jest.SpiedFunction<Source>.
Используйте jest.SpiedGetter<Source> или jest.SpiedSetter<Source>, чтобы создать тип метода получения или установки, за которым ведётся наблюдение.
© 2022 Facebook, Inc.
Licensed under the MIT License.
https://jestjs.io/docs/mock-function-api