Mock-функции
Вы можете создать mock-функцию для отслеживания её вызовов с помощью метода vi.fn
. Если вы хотите отслеживать метод существующего объекта, используйте метод vi.spyOn
:
import { vi } from 'vitest';
const fn = vi.fn();
fn('hello world');
fn.mock.calls[0] === ['hello world'];
const market = {
getApples: () => 100,
};
const getApplesSpy = vi.spyOn(market, 'getApples');
market.getApples();
getApplesSpy.mock.calls.length === 1;
Для проверки mock-функции используйте утверждения шпионов (например, toHaveBeenCalled
) в expect
. Этот справочник по API описывает доступные свойства и методы для управления поведением mock-функции.
getMockName
Тип:
() => string
Возвращает имя, присвоенное mock-функции с помощью метода
.mockName(name)
.
mockClear
Тип:
() => MockInstance
Очищает информацию о вызовах mock-функции. После вызова этого метода
spy.mock.calls
иspy.mock.results
будут возвращать пустые массивы. Это полезно для очистки mock-функции между тестами.Чтобы этот метод вызывался автоматически перед каждым тестом, включите настройку
clearMocks
в конфигурации.
mockName
Тип:
(name: string) => MockInstance
Устанавливает внутреннее имя mock-функции. Полезно для идентификации mock-функции, не прошедшей проверку.
mockImplementation
Тип:
(fn: Function) => MockInstance
Принимает функцию, которая будет использоваться в качестве реализации mock-функции.
Например:
tsconst mockFn = vi.fn().mockImplementation(apples => apples + 1); // или: vi.fn(apples => apples + 1); const NelliesBucket = mockFn(0); const BobsBucket = mockFn(1); NelliesBucket === 1; // true BobsBucket === 2; // true mockFn.mock.calls[0][0] === 0; // true mockFn.mock.calls[1][0] === 1; // true
mockImplementationOnce
Тип:
(fn: Function) => MockInstance
Принимает функцию, которая будет использоваться в качестве реализации mock-функции для одного вызова. Позволяет создавать цепочку вызовов, в которой каждый вызов функции возвращает разные результаты.
tsconst myMockFn = vi .fn() .mockImplementationOnce(() => true) .mockImplementationOnce(() => false); myMockFn(); // true myMockFn(); // false
Когда все разовые реализации использованы, будет вызвана реализация по умолчанию, установленная с помощью
vi.fn(() => defaultValue)
или.mockImplementation(() => defaultValue)
, если они были вызваны:tsconst myMockFn = vi .fn(() => 'default') .mockImplementationOnce(() => 'first call') .mockImplementationOnce(() => 'second call'); // 'first call', 'second call', 'default', 'default' console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
withImplementation
Тип:
(fn: Function, callback: () => void) => MockInstance
Тип:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
Временно заменяет реализацию mock-функции на время выполнения обратного вызова.
jsconst myMockFn = vi.fn(() => 'original'); myMockFn.withImplementation( () => 'temp', () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original'
Можно использовать с асинхронным обратным вызовом. Чтобы вернуться к исходной реализации, необходимо дождаться завершения асинхронной операции.
tstest('async callback', () => { const myMockFn = vi.fn(() => 'original'); // Используем await, так как обратный вызов асинхронный await myMockFn.withImplementation( () => 'temp', async () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original' });
Этот метод имеет приоритет над
mockImplementationOnce
.
mockRejectedValue
Тип:
(value: any) => MockInstance
Принимает значение, которое будет отклонено при вызове асинхронной функции.
tsconst asyncMock = vi.fn().mockRejectedValue(new Error('Async error')); await asyncMock(); // throws "Async error"
mockRejectedValueOnce
Тип:
(value: any) => MockInstance
Принимает значение, которое будет отклонено при одном вызове mock-функции. При использовании в цепочке, каждый последующий вызов будет возвращать отклоненное значение.
tsconst asyncMock = vi .fn() .mockResolvedValueOnce('first call') .mockRejectedValueOnce(new Error('Async error')); await asyncMock(); // first call await asyncMock(); // throws "Async error"
mockReset
Тип:
() => MockInstance
Выполняет
mockClear
и заменяет внутреннюю реализацию на пустую функцию (возвращающуюundefined
при вызове). Это полезно, когда вы хотите полностью сбросить mock-функцию в её исходное состояние.Чтобы этот метод вызывался автоматически перед каждым тестом, включите настройку
mockReset
в конфигурации.
mockRestore
Тип:
() => MockInstance
Аналогична
mockReset
, но восстанавливает внутреннюю реализацию до исходной функции.Обратите внимание, что восстановление
vi.fn()
задает пустую функцию. Восстановлениеvi.fn(impl)
восстановит реализацию доimpl
.Чтобы этот метод вызывался автоматически перед каждым тестом, включите настройку
restoreMocks
в конфигурации.
mockResolvedValue
Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено при успешном выполнении (resolve) асинхронной функции.
tsconst asyncMock = vi.fn().mockResolvedValue(43); await asyncMock(); // 43
mockResolvedValueOnce
Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено при успешном выполнении (resolve) одного вызова mock-функции. При использовании в цепочке, каждый последующий вызов будет возвращать переданное значение.
tsconst asyncMock = vi .fn() .mockResolvedValue('default') .mockResolvedValueOnce('first call') .mockResolvedValueOnce('second call'); await asyncMock(); // first call await asyncMock(); // second call await asyncMock(); // default await asyncMock(); // default
mockReturnThis
Тип:
() => MockInstance
Устанавливает внутреннюю реализацию для возврата контекста
this
.
mockReturnValue
Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращаться при каждом вызове mock-функции.
tsconst mock = vi.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
mockReturnValueOnce
Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено при одном вызове mock-функции. При использовании в цепочке, каждый последующий вызов будет возвращать переданное значение. Когда значения
mockReturnValueOnce
заканчиваются, вызывается функция, определенная вmockImplementation
или других методахmockReturn*
.tsconst myMockFn = vi .fn() .mockReturnValue('default') .mockReturnValueOnce('first call') .mockReturnValueOnce('second call'); // 'first call', 'second call', 'default', 'default' console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
mock.calls
Это массив, содержащий аргументы всех вызовов mock-функции. Каждый элемент массива содержит аргументы соответствующего вызова.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3', 'arg4');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call
['arg3', 'arg4'], // second call
];
mock.lastCall
Содержит аргументы последнего вызова mock-функции. Если mock-функция не была вызвана, вернет undefined
.
mock.results
Массив, содержащий результаты всех вызовов mock-функции. Каждый элемент массива представляет собой объект со свойствами type
и value
. Доступные типы:
'return'
- функция вернула значение без выбрасывания исключения.'throw'
- функция выбросила исключение.
Свойство value
содержит возвращенное значение или ошибку. Если функция вернула промис, то после его разрешения свойство value
станет значением, которое промис вернул.
const fn = vi.fn();
const result = fn(); // returned 'result'
try {
fn(); // threw Error
} catch {}
fn.mock.results ===
[
// first result
{
type: 'return',
value: 'result',
},
// last result
{
type: 'throw',
value: Error,
},
];
mock.instances
Это массив, содержащий все экземпляры, которые были созданы при вызове mock-функции с ключевым словом new
. Важно: это контекст (this
) mock-функции, а не возвращаемое ей значение.
WARNING
Если mock-функция была создана с помощью new MyClass()
, то mock.instances
будет массивом с одним значением:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Если вы возвращаете значение из конструктора, его не будет в массиве instances
, а вместо этого внутри results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;