Mock-Funktionen
Du kannst eine Mock-Funktion erstellen, um die Ausführung mit der Methode vi.fn
zu verfolgen. Wenn du eine Methode eines bestehenden Objekts überwachen möchtest, kannst du die Methode 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;
Du solltest Mock-Assertions (z. B. toHaveBeenCalled
) in Verbindung mit expect
verwenden, um das Ergebnis des Mocks zu überprüfen. Diese API-Referenz beschreibt verfügbare Eigenschaften und Methoden zur Manipulation des Mock-Verhaltens.
getMockImplementation
- Typ:
(...args: any) => any
Gibt die aktuelle Implementierung des Mocks zurück, sofern eine vorhanden ist.
Wenn der Mock mit vi.fn
erstellt wurde, wird die übergebene Funktion als Implementierung des Mocks betrachtet.
Wenn der Mock mit vi.spyOn
erstellt wurde, wird undefined
zurückgegeben, es sei denn, es wurde eine benutzerdefinierte Implementierung bereitgestellt.
getMockName
- Typ:
() => string
Hiermit kannst du den Namen abrufen, der dem Mock mit der Methode .mockName(name)
zugewiesen wurde.
mockClear
- Typ:
() => MockInstance
Löscht alle Informationen über jeden Aufruf. Nach dem Aufruf geben alle Eigenschaften von .mock
einen leeren Zustand zurück. Diese Methode setzt die Implementierung nicht zurück. Sie ist nützlich, um den Mock zwischen verschiedenen Assertions zurückzusetzen.
Wenn diese Methode vor jedem Test automatisch aufgerufen werden soll, kannst du die Einstellung clearMocks
in der Konfiguration aktivieren.
mockName
- Typ:
(name: string) => MockInstance
Setzt den internen Mock-Namen. Dies ist nützlich, um den Namen des Mocks zu sehen, falls eine Assertion fehlschlägt.
mockImplementation
- Typ:
(fn: Function) => MockInstance
Akzeptiert eine Funktion, die als Implementierung für den Mock verwendet wird.
import { vi } from 'vitest';
// ---cut---
const mockFn = vi.fn().mockImplementation(apples => 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
- Typ:
(fn: Function) => MockInstance
Akzeptiert eine Funktion, die beim nächsten Aufruf als Mock-Implementierung verwendet wird. Mehrere Aufrufe können verkettet werden, um unterschiedliche Ergebnisse zu erzielen.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true)
.mockImplementationOnce(() => false);
myMockFn(); // true
myMockFn(); // false
Wenn keine spezifischen Implementierungen mehr vorhanden sind, wird die Standardimplementierung verwendet, die mit vi.fn(() => defaultValue)
oder .mockImplementation(() => defaultValue)
definiert wurde, falls vorhanden:
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
- Typ:
(fn: Function, callback: () => void) => MockInstance
- Typ:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
Überschreibt die ursprüngliche Mock-Implementierung vorübergehend, während der Callback ausgeführt wird.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Kann mit einem asynchronen Callback verwendet werden. Es muss auf die Methode gewartet werden, um sicherzustellen, dass anschließend die ursprüngliche Implementierung verwendet wird.
test('async callback', () => {
const myMockFn = vi.fn(() => 'original');
// Wir erwarten diesen Aufruf, da der Callback asynchron ist
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
Beachte, dass diese Methode Vorrang vor der Methode mockImplementationOnce
hat.
mockRejectedValue
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, mit dem die asynchrone Funktion bei Aufruf eine Fehler auslöst (Promise wird rejected).
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
mockRejectedValueOnce
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, der während des nächsten Funktionsaufrufs zurückgewiesen wird. Wenn sie verkettet sind, wird jeder aufeinanderfolgende Aufruf den angegebenen Wert zurückweisen.
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
- Typ:
() => MockInstance
Verhält sich wie mockClear
und setzt die interne Implementierung auf eine leere Funktion zurück (die bei Aufruf undefined
zurückgibt). Dadurch werden auch alle "Once"-Implementierungen zurückgesetzt. Dies ist nützlich, wenn du einen Mock vollständig in den Standardzustand zurücksetzen möchtest.
Wenn diese Methode vor jedem Test automatisch aufgerufen werden soll, kannst du die Einstellung mockReset
in der Konfiguration aktivieren.
mockRestore
- Typ:
() => MockInstance
Verhält sich wie mockReset
und stellt die interne Implementierung der ursprünglichen Funktion wieder her.
Hinweis: Das Wiederherstellen eines Mocks aus vi.fn()
setzt die Implementierung auf eine leere Funktion, die undefined
zurückgibt. Das Wiederherstellen von vi.fn(impl)
stellt die Implementierung auf impl
wieder her.
Wenn diese Methode vor jedem Test automatisch aufgerufen werden soll, kannst du die Einstellung restoreMocks
in der Konfiguration aktivieren.
mockResolvedValue
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, der aufgelöst wird, wenn die asynchrone Funktion aufgerufen wird.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, der während des nächsten Funktionsaufrufs aufgelöst wird. Wenn sie verkettet sind, wird jeder aufeinanderfolgende Aufruf den angegebenen Wert auflösen.
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(); // default
mockReturnThis
- Typ:
() => MockInstance
Hiermit kannst du den this
-Kontext der Methode zurückgeben, ohne die eigentliche Implementierung auszuführen. Dies ist eine Kurzform für:
spy.mockImplementation(function () {
return this;
});
mockReturnValue
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, der bei jedem Aufruf der Mock-Funktion zurückgegeben wird.
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
- Typ:
(value: any) => MockInstance
Akzeptiert einen Wert, der während des nächsten Funktionsaufrufs zurückgegeben wird. Bei Verkettung wird jeder nachfolgende Aufruf den angegebenen Wert zurückgeben.
Wenn keine weiteren mockReturnValueOnce
-Werte vorhanden sind, wird auf die zuvor definierte Implementierung zurückgegriffen, falls vorhanden.
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
Dies ist ein Array, das alle Argumente für jeden Aufruf enthält. Jedes Element des Arrays enthält die Argumente eines Aufrufs.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call - erster Aufruf
['arg3'], // second call - zweiter Aufruf
];
mock.lastCall
Enthält die Argumente des letzten Aufrufs. Wenn der Mock nicht aufgerufen wurde, wird undefined
zurückgegeben.
mock.results
Dies ist ein Array, das alle Werte enthält, die von der Funktion zurückgegeben wurden. Ein Element des Arrays ist ein Objekt mit den Eigenschaften type
und value
. Verfügbare Typen sind:
'return'
- Funktion wurde ohne Fehler zurückgegeben.'throw'
- Funktion hat eine Exception ausgelöst.
Das Attribut value
enthält den Rückgabewert oder die ausgelöste Exception. Wenn die Funktion eine Promise zurückgegeben hat, enthält value
den aufgelösten Wert und nicht die Promise selbst, es sei denn, die Promise wurde nie aufgelöst.
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
const result = fn(); // returned 'result' - gab 'result' zurück
try {
fn(); // threw Error - warf Fehler
} catch {}
fn.mock.results ===
[
// first result - erstes Ergebnis
{
type: 'return',
value: 'result',
},
// last result - letztes Ergebnis
{
type: 'throw',
value: Error,
},
];
mock.invocationCallOrder
Dies gibt ein Array von Zahlen zurück, das die Ausführungsreihenfolge aller definierten Mocks widerspiegelt.
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];
mock.instances
Dies ist ein Array, das alle Instanzen enthält, die instanziiert wurden, als der Mock mit dem Schlüsselwort new
aufgerufen wurde. Beachte, dass dies der tatsächliche Kontext (this
) der Funktion ist und nicht der Rückgabewert.
WARNING
Wenn der Mock mit new MyClass()
instanziiert wurde, ist mock.instances
ein Array mit einem Wert:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Wenn der Konstruktor einen Wert zurückgibt, befindet sich dieser nicht im Array instances
, sondern stattdessen in results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;