Mock Függvények
Létrehozhat egy mock függvényt, hogy nyomon kövesse annak végrehajtását a vi.fn
metódussal. Ha egy már létező objektum metódusát szeretné megfigyelni, használja a vi.spyOn
metódust:
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;
A mock eredmények ellenőrzéséhez használjon mock-ellenőrzéseket (pl. toHaveBeenCalled
) az expect
függvény segítségével. Ez az API referencia a mock viselkedésének módosításához szükséges tulajdonságokat és metódusokat ismerteti.
TIP
Az alábbi típusokban az egyéni függvény implementációját a <T>
generikus jelöli.
getMockImplementation
function getMockImplementation(): T | undefined;
Visszaadja az aktuális mock implementációt, ha van ilyen.
Ha a mock a vi.fn
segítségével jött létre, akkor a megadott metódust fogja használni mock implementációként.
Ha a mock a vi.spyOn
segítségével jött létre, akkor undefined
értéket ad vissza, hacsak nem adtak meg egyéni implementációt.
getMockName
function getMockName(): string;
Ezzel a metódussal lekérdezhető a mocknak a .mockName(name)
metódussal hozzárendelt neve. Alapértelmezés szerint vi.fn()
értéket ad vissza.
mockClear
function mockClear(): MockInstance<T>;
Törli a hívásokkal kapcsolatos összes információt. A mockClear
meghívása után a .mock
összes tulajdonsága visszaáll az eredeti állapotába. Ez a metódus nem állítja vissza az implementációkat. Hasznos a mockok állapotának tisztítására a különböző tesztállítások között.
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']]);
// hívási előzmények törlése, de a mock implementáció megőrzése
spy.mockClear();
expect(spy.mock.calls).toEqual([]);
expect(person.greet('Bob')).toBe('mocked');
expect(spy.mock.calls).toEqual([['Bob']]);
Ahhoz, hogy ezt a metódust automatikusan meghívja minden teszt előtt, engedélyezze a clearMocks
beállítást a konfigurációban.
mockName
function mockName(name: string): MockInstance<T>;
Beállítja a mock belső nevét. Ez hasznos a mock azonosításához, ha egy tesztállás hibát jelez.
mockImplementation
function mockImplementation(fn: T): MockInstance<T>;
Elfogad egy függvényt, amelyet mock implementációként használ. A TypeScript elvárja, hogy az argumentumok és a visszatérési típus megegyezzen az eredeti függvény típusával.
const mockFn = vi.fn().mockImplementation((apples: number) => apples + 1);
// vagy: 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>;
Elfogad egy függvényt, amelyet mock implementációként használ. A TypeScript elvárja, hogy az argumentumok és a visszatérési típus megegyezzen az eredeti függvény típusával. Ez a metódus láncolható, hogy több függvényhívás esetén különböző eredményeket biztosítson.
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true) // 1. hívás
.mockImplementationOnce(() => false); // 2. hívás
myMockFn(); // 1. hívás: true
myMockFn(); // 2. hívás: false
Amikor a mockolt függvénynek elfogynak az egyszeri implementációi, meghívja az alapértelmezett implementációt, amelyet a vi.fn(() => defaultValue)
vagy .mockImplementation(() => defaultValue)
hívásokkal állítottak be:
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>>;
Ideiglenesen felülírja az eredeti mock implementációt, amíg a visszahívás végrehajtódik.
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Használható aszinkron visszahívással. A metódust meg kell várni, hogy utána az eredeti implementáció használható legyen.
test('async callback', async () => {
const myMockFn = vi.fn(() => 'original');
// Ezt a hívást meg kell várni, mivel a visszahívás aszinkron
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
Vegye figyelembe, hogy ez a metódus elsőbbséget élvez a mockImplementationOnce
felett.
mockRejectedValue
function mockRejectedValue(value: unknown): MockInstance<T>;
Elfogad egy hibát, amelyet az aszinkron függvény meghívásakor elutasításra kerül.
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // kivételt dob: Error('Async error')
mockRejectedValueOnce
function mockRejectedValueOnce(value: unknown): MockInstance<T>;
Elfogad egy értéket, amelyet a következő függvényhívás során elutasításra kerül. Ha láncolva van, minden egymást követő hívás elutasítja a megadott értéket.
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // 'first call'
await asyncMock(); // kivételt dob: Error('Async error')
mockReset
function mockReset(): MockInstance<T>;
Ugyanazt teszi, mint a mockClear
, emellett visszaállítja a belső implementációt az eredeti függvényre. Ez az összes "once" implementációt is alaphelyzetbe állítja.
Vegye figyelembe, hogy a vi.fn()
-ből származó mock visszaállítása egy üres függvényre állítja az implementációt, amely undefined
értékkel tér vissza. A vi.fn(impl)
-ből származó mock visszaállítása visszaállítja az implementációt impl
-re.
Ez akkor hasznos, ha egy mockot az eredeti állapotába szeretne visszaállítani.
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']]);
// hívási előzmények törlése és implementáció visszaállítása, de a metódus továbbra is megfigyelt marad
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']]);
Ahhoz, hogy ezt a metódust automatikusan meghívja minden teszt előtt, engedélyezze a mockReset
beállítást a konfigurációban.
mockRestore
function mockRestore(): MockInstance<T>;
Ugyanazt teszi, mint a mockReset
, emellett visszaállítja a megfigyelt objektumok eredeti descriptor-ait.
Vegye figyelembe, hogy a vi.fn()
-ből származó mock visszaállítása egy üres függvényre állítja az implementációt, amely undefined
értékkel tér vissza. A vi.fn(impl)
-ből származó mock visszaállítása visszaállítja az implementációt impl
-re.
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']]);
// hívási előzmények törlése és a megfigyelt objektum metódusának visszaállítása
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([]);
Ahhoz, hogy ezt a metódust automatikusan meghívja minden teszt előtt, engedélyezze a restoreMocks
beállítást a konfigurációban.
mockResolvedValue
function mockResolvedValue(value: Awaited<ReturnType<T>>): MockInstance<T>;
Elfogad egy értéket, amelyet az aszinkron függvény meghívásakor feloldásra kerül. A TypeScript csak olyan értékeket fogad el, amelyek megegyeznek az eredeti függvény visszatérési típusával.
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
function mockResolvedValueOnce(value: Awaited<ReturnType<T>>): MockInstance<T>;
Elfogad egy értéket, amelyet a következő függvényhívás során felold. A TypeScript csak olyan értékeket fogad el, amelyek megegyeznek az eredeti függvény visszatérési típusával. Ha láncolva van, minden egymást követő hívás feloldja a megadott értéket.
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>;
Ezt akkor használja, ha a this
kontextust kell visszaadnia a metódusból az aktuális implementáció meghívása nélkül. Ez egy rövidítés a következőre:
spy.mockImplementation(function () {
return this;
});
mockReturnValue
function mockReturnValue(value: ReturnType<T>): MockInstance<T>;
Elfogad egy értéket, amellyel a mock függvény minden hívásakor visszatér. A TypeScript csak olyan értékeket fogad el, amelyek megegyeznek az eredeti függvény visszatérési típusával.
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
function mockReturnValueOnce(value: ReturnType<T>): MockInstance<T>;
Elfogad egy értéket, amellyel a mock függvény minden hívásakor visszatér. A TypeScript csak olyan értékeket fogad el, amelyek megegyeznek az eredeti függvény visszatérési típusával.
Amikor a mockolt függvénynek elfogynak az egyszeri implementációi, meghívja az alapértelmezett implementációt, amelyet a vi.fn(() => defaultValue)
vagy .mockImplementation(() => defaultValue)
hívásokkal állítottak be:
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>[];
Ez egy tömb, amely az összes argumentumot tartalmazza az egyes hívásokhoz. A tömb minden eleme egy adott hívás argumentumait tartalmazza.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // első hívás
['arg3'], // második hívás
];
mock.lastCall
const lastCall: Parameters<T> | undefined;
Ez az utolsó hívás argumentumait tartalmazza. Ha a mockot nem hívták meg, undefined
értéket ad vissza.
mock.results
interface MockResultReturn<T> {
type: 'return';
/**
* A függvényből visszatérített érték.
* Ha a függvény Promise-t adott vissza, akkor ez egy feloldott érték lesz.
*/
value: T;
}
interface MockResultIncomplete {
type: 'incomplete';
value: undefined;
}
interface MockResultThrow {
type: 'throw';
/**
* A függvény végrehajtása során dobott hiba.
*/
value: any;
}
type MockResult<T> =
| MockResultReturn<T>
| MockResultThrow
| MockResultIncomplete;
const results: MockResult<ReturnType<T>>[];
Ez egy tömb, amely az összes értéket tartalmazza, amelyet a függvény visszatérített. A tömb minden eleme egy objektum, amely type
és value
tulajdonságokkal rendelkezik. A rendelkezésre álló típusok:
'return'
- a függvény kivétel dobása nélkül tért vissza.'throw'
- a függvény kivételt dobott.
A value
tulajdonság tartalmazza a visszatérített értéket vagy a dobott hibát. Ha a függvény Promise
-t adott vissza, akkor a type
tulajdonság mindig 'return'
lesz, még akkor is, ha a promise elutasításra került.
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
const result = fn(); // 'result' értéket adott vissza
try {
fn(); // hibát dobott
} catch {}
fn.mock.results ===
[
// első eredmény
{
type: 'return',
value: 'result',
},
// utolsó eredmény
{
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>>>[];
Egy tömb, amely az összes értéket tartalmazza, amelyet a függvény feloldott vagy elutasított.
Ez a tömb üres lesz, ha a függvény soha nem került feloldásra vagy elutasításra.
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[];
Ez a tulajdonság a mock függvény meghívási sorrendjét mutatja. Ez egy számokból álló tömb, amely közös az összes definiált mock között.
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>[];
Ez a tulajdonság egy tömb, amely a this
értékeket tartalmazza, amelyeket a mock függvény minden hívása során felhasználtak.
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>[];
Ez a tulajdonság egy tömb, amely az összes olyan példányt tartalmazza, amelyek akkor jöttek létre, amikor a mockot a new
kulcsszóval hívták meg. Fontos megjegyezni, hogy ez a függvény tényleges kontextusa (this
), nem pedig visszatérési érték.
WARNING
Ha a mockot new MyClass()
-szal példányosították, akkor a mock.instances
egy egyelemű tömb lesz:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Ha egy értéket ad vissza a konstruktorból, az nem lesz az instances
tömbben, hanem a results
tömbben található meg:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;