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-функций используйте утверждения mock (например, toHaveBeenCalled) в expect. Этот справочник API описывает доступные свойства и методы для управления поведением mock-функций.
getMockImplementation
- Тип:
(...args: any) => any
Возвращает текущую реализацию mock-функции, если она задана.
Если mock-функция была создана с помощью vi.fn, она будет использовать переданную функцию в качестве реализации.
Если mock-функция была создана с помощью vi.spyOn, она вернет undefined, если пользовательская реализация не была предоставлена.
getMockName
- Тип:
() => string
Используйте этот метод, чтобы получить имя, присвоенное mock-функции с помощью метода .mockName(name).
mockClear
- Тип:
() => MockInstance
Очищает информацию обо всех вызовах mock-функции. После вызова все свойства в .mock будут возвращать значения по умолчанию. Это полезно для очистки mock-функции между различными утверждениями.
Если вы хотите, чтобы этот метод вызывался автоматически перед каждым тестом, вы можете включить параметр clearMocks в конфигурации.
mockName
- Тип:
(name: string) => MockInstance
Устанавливает внутреннее имя mock-функции. Это полезно для идентификации mock-функции при сбое утверждения.
mockImplementation
- Тип:
(fn: Function) => MockInstance
Принимает функцию, которая будет использоваться в качестве реализации mock-функции.
import { vi } from 'vitest';
// ---cut---
const 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; // truemockImplementationOnce
- Тип:
(fn: Function) => MockInstance
Принимает функцию, которая будет использоваться в качестве реализации mock-функции только при следующем вызове. Можно объединять в цепочку, чтобы последовательные вызовы функций давали разные результаты.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true)
.mockImplementationOnce(() => false);
myMockFn(); // true
myMockFn(); // falseКогда у mock-функции заканчиваются реализации, установленные с помощью mockImplementationOnce, она вызывает реализацию по умолчанию, которая была установлена с помощью vi.fn(() => defaultValue) или .mockImplementation(() => defaultValue), если они были вызваны ранее.
import { vi } from 'vitest';
// ---cut---
const 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-функции на время выполнения обратного вызова.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'Может использоваться с асинхронным обратным вызовом. Чтобы использовать исходную реализацию впоследствии, необходимо дождаться завершения асинхронного обратного вызова.
test('async callback', () => {
const myMockFn = vi.fn(() => 'original');
// Мы ожидаем этот вызов, так как обратный вызов является асинхронным
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});Обратите внимание, что этот метод имеет приоритет над mockImplementationOnce.
mockRejectedValue
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет отклонено при вызове асинхронной mock-функции.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"mockRejectedValueOnce
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет отклонено при следующем вызове mock-функции. При объединении в цепочку, каждый последующий вызов будет отклонять указанное значение.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // first call
await asyncMock(); // throws "Async error"mockReset
- Тип:
() => MockInstance
Делает то же, что и mockClear, и устанавливает внутреннюю реализацию в пустую функцию (возвращающую undefined при вызове). Это также сбрасывает все реализации, установленные с помощью "once". Это полезно, когда вы хотите полностью сбросить mock-функцию в состояние по умолчанию.
Если вы хотите, чтобы этот метод вызывался автоматически перед каждым тестом, вы можете включить параметр mockReset в конфигурации.
mockRestore
- Тип:
() => MockInstance
Делает то же, что и mockReset, и возвращает внутреннюю реализацию к исходной функции.
Обратите внимание, что восстановление mock-функции, созданной с помощью vi.fn(), установит реализацию в пустую функцию, которая возвращает undefined. Восстановление vi.fn(impl) восстановит реализацию до impl.
Если вы хотите, чтобы этот метод вызывался автоматически перед каждым тестом, вы можете включить параметр restoreMocks в конфигурации.
mockResolvedValue
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено успешно (resolved) при вызове асинхронной mock-функции.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42mockResolvedValueOnce
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено успешно (resolved) при следующем вызове mock-функции. Если объединено в цепочку, каждый последующий вызов будет возвращать указанное значение.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
.fn()
.mockResolvedValue('default')
.mockResolvedValueOnce('first call')
.mockResolvedValueOnce('second call');
await asyncMock(); // first call
await asyncMock(); // second call
await asyncMock(); // default
await asyncMock(); // defaultmockReturnThis
- Тип:
() => MockInstance
Используйте это, если вам нужно вернуть контекст this из метода, не вызывая фактическую реализацию. Это сокращение для:
spy.mockImplementation(function () {
return this;
});mockReturnValue
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращаться при каждом вызове mock-функции.
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43mockReturnValueOnce
- Тип:
(value: any) => MockInstance
Принимает значение, которое будет возвращено во время следующего вызова функции. Если объединено в цепочку, каждый последующий вызов будет возвращать указанное значение.
Когда больше нет значений mockReturnValueOnce для использования, mock-функция вернется к ранее определенной реализации, если она есть.
import { vi } from 'vitest';
// ---cut---
const 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');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call
['arg3'], // second call
];mock.lastCall
Содержит аргументы последнего вызова mock-функции. Если mock-функция не была вызвана, вернет undefined.
mock.results
Это массив, содержащий все результаты, возвращённые mock-функцией. Каждый элемент массива - это объект со свойствами type и value. Доступные типы:
'return'- функция завершилась успешно.'throw'- функция выбросила исключение.
Свойство value содержит возвращенное значение или выброшенную ошибку. Если функция вернула promise, value будет разрешённым значением, а не самим Promise, если разрешение произошло.
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
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.invocationCallOrder
Порядок выполнения вызовов mock-функций. Возвращает массив чисел, которые являются общими для всех определенных mock-функций.
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];mock.instances
Это массив, содержащий все экземпляры, которые были созданы при вызове mock-функции с ключевым словом new. Обратите внимание, что это фактический контекст (this) функции, а не возвращаемое ею значение.
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;