Mockování funkcí
Můžete vytvořit mockovací funkci (mock) pro sledování jejího provádění pomocí metody vi.fn
. Pokud chcete sledovat metodu existujícího objektu, můžete použít metodu 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;
Pro ověření chování špiona byste měli použít asertace špionáže (např. toHaveBeenCalled
) s expect
. Tento referenční manuál API popisuje dostupné vlastnosti a metody pro manipulaci s chováním mocků.
getMockName
Typ:
() => string
Vrací jméno mocku nastavené metodou
.mockName(name)
.
mockClear
Typ:
() => MockInstance
Vymaže veškeré informace o voláních mocku. Po zavolání této metody budou
spy.mock.calls
aspy.mock.results
prázdná pole. To je užitečné pro resetování mocku mezi jednotlivými asercemi.Pokud chcete, aby byla tato metoda volána automaticky před každým testem, povolte v konfiguraci nastavení
clearMocks
.
mockName
Typ:
(name: string) => MockInstance
Nastaví interní jméno mocku. To je užitečné pro identifikaci mocku, který selhal při assertaci.
mockImplementation
Typ:
(fn: Function) => MockInstance
Přijímá funkci, která bude použita jako implementace mocku.
Například:
tsconst mockFn = vi.fn().mockImplementation(apples => apples + 1); // nebo: 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
Přijímá funkci, která bude použita jako implementace mocku pro jedno volání. Lze ji řetězit, takže jednotlivá volání funkce produkují různé výsledky.
tsconst myMockFn = vi .fn() .mockImplementationOnce(() => true) .mockImplementationOnce(() => false); myMockFn(); // true myMockFn(); // false
Když mockovaná funkce vyčerpá implementace nastavené pomocí
mockImplementationOnce
, použije výchozí implementaci nastavenou pomocívi.fn(() => defaultValue)
nebo.mockImplementation(() => defaultValue)
, pokud byla volána:tsconst 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>
Dočasně nahradí původní implementaci mocku po dobu provádění callbacku.
jsconst myMockFn = vi.fn(() => 'original'); myMockFn.withImplementation( () => 'temp', () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original'
Lze použít s asynchronním callbackem. Na metodu se musí počkat (await), aby byla následně obnovena původní implementace.
tstest('async callback', () => { const myMockFn = vi.fn(() => 'original'); // Čekáme na toto volání, protože callback je asynchronní await myMockFn.withImplementation( () => 'temp', async () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original' });
Má také přednost před
mockImplementationOnce
.
mockRejectedValue
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude použita jako zamítnutá hodnota (rejected value), když bude volána asynchronní funkce.
tsconst asyncMock = vi.fn().mockRejectedValue(new Error('Async error')); await asyncMock(); // vyhodí "Async error"
mockRejectedValueOnce
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude zamítnuta (rejected) při jednom volání mock funkce. Pokud je zřetězena, každé po sobě jdoucí volání zamítne předanou hodnotu.
tsconst asyncMock = vi .fn() .mockResolvedValueOnce('first call') .mockRejectedValueOnce(new Error('Async error')); await asyncMock(); // first call await asyncMock(); // vyhodí "Async error"
mockReset
Typ:
() => MockInstance
Funguje jako
mockClear
a nastaví vnitřní implementaci na prázdnou funkci (která při zavolání vracíundefined
). To je užitečné, když chcete mock kompletně resetovat do jeho počátečního stavu.Pokud chcete, aby byla tato metoda volána automaticky před každým testem, povolte v konfiguraci nastavení
mockReset
.
mockRestore
Typ:
() => MockInstance
Funguje jako
mockReset
a obnoví vnitřní implementaci na původní funkci.Upozorňujeme, že obnovení mocku vytvořeného pomocí
vi.fn()
nastaví implementaci na prázdnou funkci, která vracíundefined
. Obnovenívi.fn(impl)
obnoví implementaci naimpl
.Pokud chcete, aby byla tato metoda volána automaticky před každým testem, povolte v konfiguraci nastavení
restoreMocks
.
mockResolvedValue
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude použita jako vyřešená hodnota (resolved value), když bude volána asynchronní funkce.
tsconst asyncMock = vi.fn().mockResolvedValue(43); await asyncMock(); // 43
mockResolvedValueOnce
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude vyřešena (resolved) pro jedno volání mock funkce. Pokud je zřetězena, každé po sobě jdoucí volání vyřeší předanou hodnotu.
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
Typ:
() => MockInstance
Nastaví vnitřní implementaci tak, aby vracela kontext
this
.
mockReturnValue
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude vrácena při každém zavolání mock funkce.
tsconst mock = vi.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
mockReturnValueOnce
Typ:
(value: any) => MockInstance
Přijímá hodnotu, která bude vrácena pro jedno volání mock funkce. Pokud je zřetězena, každé po sobě jdoucí volání vrátí předanou hodnotu. Pokud již nejsou k dispozici žádné hodnoty pro
mockReturnValueOnce
, bude zavolána funkce určená pomocímockImplementation
nebo jiných metodmockReturn*
.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
Toto je pole obsahující argumenty pro jednotlivá volání mocku. Každá položka pole představuje argumenty daného volání.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3', 'arg4');
fn.mock.calls ===
[
['arg1', 'arg2'], // první volání
['arg3', 'arg4'], // druhé volání
];
mock.lastCall
Obsahuje argumenty posledního volání mocku. Pokud mock nebyl zavolán, vrátí undefined
.
mock.results
Toto je pole obsahující výsledky volání mocku. Každá položka pole je objekt s vlastnostmi type
a value
. Dostupné typy zahrnují:
'return'
- funkce se vrátila bez vyvolání chyby.'throw'
- funkce vyvolala výjimku.
Vlastnost value
obsahuje vrácenou hodnotu nebo vyvolanou výjimku. Pokud funkce vrátila Promise, po jejím vyřešení bude vlastnost value
obsahovat hodnotu, na kterou se Promise vyřešila.
const fn = vi.fn();
const result = fn(); // vrátil 'result'
try {
fn(); // vyvolal chybu
} catch {}
fn.mock.results ===
[
// první výsledek
{
type: 'return',
value: 'result',
},
// poslední výsledek
{
type: 'throw',
value: Error,
},
];
mock.instances
Toto je pole obsahující všechny instance vytvořené při zavolání mocku s klíčovým slovem new
. Upozorňujeme, že se jedná o skutečný kontext (this
) funkce, nikoli o vrácenou hodnotu.
WARNING
Pokud byl mock vytvořen pomocí new MyClass()
, pak bude mock.instances
pole obsahující jednu hodnotu:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Pokud konstruktor vrací hodnotu, nebude uložena v poli instances
, ale v poli results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;