Mock-Funktionen
Sie können eine Mock-Funktion mit vi.fn
erstellen, um deren Ausführung zu verfolgen. Wenn Sie eine Methode auf einem bereits vorhandenen Objekt verfolgen möchten, können Sie vi.spyOn
verwenden:
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;
Sie sollten Mock-Assertions (z. B. toHaveBeenCalled
) mit expect
verwenden, um das Mock-Ergebnis zu überprüfen. Diese API-Referenz beschreibt die verfügbaren Eigenschaften und Methoden zur Manipulation des Mock-Verhaltens.
TIP
Die benutzerdefinierte Funktionsimplementierung in den folgenden Typen ist mit einem generischen <T>
gekennzeichnet.
getMockImplementation
function getMockImplementation(): T | undefined;
Gibt die aktuelle Mock-Implementierung zurück, sofern eine existiert.
Wenn der Mock mit vi.fn
erstellt wurde, wird die bereitgestellte Methode als Mock-Implementierung verwendet.
Wenn der Mock mit vi.spyOn
erstellt wurde, gibt es undefined
zurück, es sei denn, es wurde eine benutzerdefinierte Implementierung bereitgestellt.
getMockName
function getMockName(): string;
Verwenden Sie diese Methode, um den Namen zurückzugeben, der dem Mock mittels der .mockName(name)
-Methode zugewiesen wurde. Standardmäßig wird vi.fn()
zurückgegeben.
mockClear
function mockClear(): MockInstance<T>;
Löscht alle Informationen über jeden Aufruf. Nach dem Aufruf kehren alle Eigenschaften auf .mock
in ihren Ausgangszustand zurück. Diese Methode setzt jedoch keine Implementierungen zurück. Sie ist nützlich, um Mocks zwischen verschiedenen Assertions zu bereinigen.
const person = {
greet: (name: string) => `Hello ${name}`,
};
const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked');
expect(person.greet('Alice')).toBe('mocked');
expect(spy.mock.calls).toEqual([['Alice']]);
// Aufrufhistorie löschen, aber Mock-Implementierung erhalten
spy.mockClear();
expect(spy.mock.calls).toEqual([]);
expect(person.greet('Bob')).toBe('mocked');
expect(spy.mock.calls).toEqual([['Bob']]);
Um diese Methode vor jedem Test automatisch aufzurufen, aktivieren Sie die Einstellung clearMocks
in der Konfiguration.
mockName
function mockName(name: string): MockInstance<T>;
Setzt den internen Mock-Namen. Dies ist nützlich, um den Mock zu identifizieren, wenn eine Assertion fehlschlägt.
mockImplementation
function mockImplementation(fn: T): MockInstance<T>;
Akzeptiert eine Funktion, die als Mock-Implementierung verwendet werden soll. TypeScript erwartet, dass die Argumente und der Rückgabetyp denen der ursprünglichen Funktion entsprechen.
const mockFn = vi.fn().mockImplementation((apples: number) => apples + 1);
// oder: 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
function mockImplementationOnce(fn: T): MockInstance<T>;
Akzeptiert eine Funktion, die als Mock-Implementierung verwendet werden soll. TypeScript erwartet, dass die Argumente und der Rückgabetyp denen der ursprünglichen Funktion entsprechen. Diese Methode kann verkettet werden, um unterschiedliche Ergebnisse für mehrere Funktionsaufrufe zu erzeugen.
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true) // 1. Aufruf
.mockImplementationOnce(() => false); // 2. Aufruf
myMockFn(); // 1. Aufruf: true
myMockFn(); // 2. Aufruf: false
Wenn der gemockten Funktion die Implementierungen ausgehen, wird die Standardimplementierung aufgerufen, die mit vi.fn(() => defaultValue)
oder .mockImplementation(() => defaultValue)
gesetzt wurde, sofern diese zuvor aufgerufen wurden:
const myMockFn = vi
.fn(() => 'default')
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call');
// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
withImplementation
function withImplementation(fn: T, cb: () => void): MockInstance<T>;
function withImplementation(
fn: T,
cb: () => Promise<void>
): Promise<MockInstance<T>>;
Überschreibt die ursprüngliche Mock-Implementierung vorübergehend, während der Callback ausgeführt wird.
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Kann mit einem asynchronen Callback verwendet werden. Die Methode muss mit await
aufgerufen werden, um die ursprüngliche Implementierung danach verwenden zu können.
test('async callback', async () => {
const myMockFn = vi.fn(() => 'original');
// Wir warten auf diesen Aufruf, da der Callback asynchron ist
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
Beachten Sie, dass diese Methode Vorrang vor mockImplementationOnce
hat.
mockRejectedValue
function mockRejectedValue(value: unknown): MockInstance<T>;
Akzeptiert einen Fehler, der abgelehnt wird, wenn die asynchrone Funktion aufgerufen wird.
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // wirft Error('Async error')
mockRejectedValueOnce
function mockRejectedValueOnce(value: unknown): MockInstance<T>;
Akzeptiert einen Wert, der beim nächsten Funktionsaufruf abgelehnt wird. Wenn verkettet, wird jeder aufeinanderfolgende Aufruf den angegebenen Wert ablehnen.
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // 'first call'
await asyncMock(); // wirft Error('Async error')
mockReset
function mockReset(): MockInstance<T>;
Führt die gleichen Aktionen wie mockClear
aus und setzt zusätzlich die interne Implementierung auf die ursprüngliche Funktion zurück. Dies setzt auch alle "once"-Implementierungen zurück.
Beachten Sie, dass das Zurücksetzen eines Mocks, der mit vi.fn()
erstellt wurde, die Implementierung auf eine leere Funktion setzt, die undefined
zurückgibt. Das Zurücksetzen eines Mocks, der mit vi.fn(impl)
erstellt wurde, stellt die Implementierung auf impl
wieder her.
Dies ist nützlich, wenn Sie einen Mock in seinen ursprünglichen Zustand zurücksetzen möchten.
const person = {
greet: (name: string) => `Hello ${name}`,
};
const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked');
expect(person.greet('Alice')).toBe('mocked');
expect(spy.mock.calls).toEqual([['Alice']]);
// Aufrufhistorie löschen und Implementierung zurücksetzen, aber die Methode wird weiterhin überwacht
spy.mockReset();
expect(spy.mock.calls).toEqual([]);
expect(person.greet).toBe(spy);
expect(person.greet('Bob')).toBe('Hello Bob');
expect(spy.mock.calls).toEqual([['Bob']]);
Um diese Methode vor jedem Test automatisch aufzurufen, aktivieren Sie die Einstellung mockReset
in der Konfiguration.
mockRestore
function mockRestore(): MockInstance<T>;
Führt die gleichen Aktionen wie mockReset
aus und stellt zusätzlich die ursprünglichen Deskriptoren von gespionten Objekten wieder her.
Beachten Sie, dass das Wiederherstellen eines Mocks, der mit vi.fn()
erstellt wurde, die Implementierung auf eine leere Funktion setzt, die undefined
zurückgibt. Das Wiederherstellen eines Mocks, der mit vi.fn(impl)
erstellt wurde, stellt die Implementierung auf impl
wieder her.
const person = {
greet: (name: string) => `Hello ${name}`,
};
const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked');
expect(person.greet('Alice')).toBe('mocked');
expect(spy.mock.calls).toEqual([['Alice']]);
// Aufrufhistorie löschen und die überwachte Objektmethode wiederherstellen
spy.mockRestore();
expect(spy.mock.calls).toEqual([]);
expect(person.greet).not.toBe(spy);
expect(person.greet('Bob')).toBe('Hello Bob');
expect(spy.mock.calls).toEqual([]);
Um diese Methode vor jedem Test automatisch aufzurufen, aktivieren Sie die Einstellung restoreMocks
in der Konfiguration.
mockResolvedValue
function mockResolvedValue(value: Awaited<ReturnType<T>>): MockInstance<T>;
Akzeptiert einen Wert, der als Promise aufgelöst wird, wenn die asynchrone Funktion aufgerufen wird. TypeScript akzeptiert nur Werte, die dem Rückgabetyp der ursprünglichen Funktion entsprechen.
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
function mockResolvedValueOnce(value: Awaited<ReturnType<T>>): MockInstance<T>;
Akzeptiert einen Wert, der beim nächsten Funktionsaufruf als Promise aufgelöst wird. TypeScript akzeptiert nur Werte, die dem Rückgabetyp der ursprünglichen Funktion entsprechen. Wenn verkettet, wird jeder aufeinanderfolgende Aufruf den angegebenen Wert auflösen.
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(); // default
mockReturnThis
function mockReturnThis(): MockInstance<T>;
Verwenden Sie dies, wenn Sie den this
-Kontext der Methode zurückgeben müssen, ohne die tatsächliche Implementierung aufzurufen. Dies ist eine Kurzform für:
spy.mockImplementation(function () {
return this;
});
mockReturnValue
function mockReturnValue(value: ReturnType<T>): MockInstance<T>;
Akzeptiert einen Wert, der immer dann zurückgegeben wird, wenn die Mock-Funktion aufgerufen wird. TypeScript akzeptiert nur Werte, die dem Rückgabetyp der ursprünglichen Funktion entsprechen.
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
function mockReturnValueOnce(value: ReturnType<T>): MockInstance<T>;
Akzeptiert einen Wert, der immer dann zurückgegeben wird, wenn die Mock-Funktion aufgerufen wird. TypeScript akzeptiert nur Werte, die dem Rückgabetyp der ursprünglichen Funktion entsprechen.
Wenn der gemockten Funktion die Implementierungen ausgehen, wird die Standardimplementierung aufgerufen, die mit vi.fn(() => defaultValue)
oder .mockImplementation(() => defaultValue)
gesetzt wurde, sofern diese zuvor aufgerufen wurden:
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
const calls: Parameters<T>[];
Dies ist ein Array, das alle Argumente für jeden Aufruf enthält. Jedes Element des Arrays enthält die Argumente des jeweiligen Aufrufs.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // erster Aufruf
['arg3'], // zweiter Aufruf
];
mock.lastCall
const lastCall: Parameters<T> | undefined;
Dies enthält die Argumente des letzten Aufrufs. Ist der Mock nicht aufgerufen worden, wird undefined
zurückgegeben.
mock.results
interface MockResultReturn<T> {
type: 'return';
/**
* Der Wert, der von der Funktion zurückgegeben wurde.
* Wenn die Funktion ein Promise zurückgegeben hat, dann ist dies der aufgelöste Wert.
*/
value: T;
}
interface MockResultIncomplete {
type: 'incomplete';
value: undefined;
}
interface MockResultThrow {
type: 'throw';
/**
* Ein Fehler, der während der Funktionsausführung geworfen wurde.
*/
value: any;
}
type MockResult<T> =
| MockResultReturn<T>
| MockResultThrow
| MockResultIncomplete;
const results: MockResult<ReturnType<T>>[];
Dies ist ein Array, das alle Ergebnisse der Funktionsaufrufe enthält. Ein Element des Arrays ist ein Objekt mit den Eigenschaften type
und value
. Verfügbare Typen sind:
'return'
- Die Funktion wurde ohne das Werfen einer Exception erfolgreich beendet.'throw'
- Die Funktion hat eine Exception geworfen.
Die Eigenschaft value
enthält den zurückgegebenen Wert oder den geworfenen Fehler. Wenn die Funktion ein Promise
zurückgegeben hat, wird der Typ des Ergebnisses immer 'return'
sein, auch wenn das Promise abgelehnt wurde.
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
const result = fn(); // hat 'result' zurückgegeben
try {
fn(); // hat einen Error geworfen
} catch {}
fn.mock.results ===
[
// erstes Ergebnis
{
type: 'return',
value: 'result',
},
// letztes Ergebnis
{
type: 'throw',
value: Error,
},
];
mock.settledResults
interface MockSettledResultFulfilled<T> {
type: 'fulfilled';
value: T;
}
interface MockSettledResultRejected {
type: 'rejected';
value: any;
}
export type MockSettledResult<T> =
| MockSettledResultFulfilled<T>
| MockSettledResultRejected;
const settledResults: MockSettledResult<Awaited<ReturnType<T>>>[];
Ein Array, das alle Werte enthält, die von der Funktion erfolgreich aufgelöst oder abgelehnt wurden.
Dieses Array bleibt leer, wenn die Funktion nie aufgelöst oder abgelehnt wurde.
const fn = vi.fn().mockResolvedValueOnce('result');
const result = fn();
fn.mock.settledResults === [];
await result;
fn.mock.settledResults ===
[
{
type: 'fulfilled',
value: 'result',
},
];
mock.invocationCallOrder
const invocationCallOrder: number[];
Diese Eigenschaft gibt die Reihenfolge der Ausführung der Mock-Funktion zurück. Es ist ein Array von Zahlen, die von allen definierten Mocks gemeinsam genutzt werden.
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];
mock.contexts
const contexts: ThisParameterType<T>[];
Diese Eigenschaft ist ein Array von this
-Werten, die bei jedem Aufruf der Mock-Funktion verwendet wurden.
const fn = vi.fn();
const context = {};
fn.apply(context);
fn.call(context);
fn.mock.contexts[0] === context;
fn.mock.contexts[1] === context;
mock.instances
const instances: ReturnType<T>[];
Diese Eigenschaft ist ein Array, das alle Instanzen enthält, die erstellt wurden, als der Mock mit dem Schlüsselwort new
aufgerufen wurde. Beachten Sie, dass dies der tatsächliche this
-Kontext der Funktion ist, kein Rückgabewert.
WARNING
Wenn der Mock mit new MyClass()
instanziiert wurde, enthält mock.instances
ein Array mit einem Wert:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Wenn Sie einen Wert aus dem Konstruktor zurückgeben, wird er nicht im instances
-Array, sondern stattdessen im results
-Array enthalten sein:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;