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:
() => stringVrací jméno mocku nastavené metodou
.mockName(name).
mockClear
Typ:
() => MockInstanceVymaže veškeré informace o voláních mocku. Po zavolání této metody budou
spy.mock.callsaspy.mock.resultsprá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) => MockInstanceNastaví interní jméno mocku. To je užitečné pro identifikaci mocku, který selhal při assertaci.
mockImplementation
Typ:
(fn: Function) => MockInstancePř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) => MockInstancePř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(); // falseKdyž 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) => MockInstanceTyp:
(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) => MockInstancePř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) => MockInstancePř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:
() => MockInstanceFunguje jako
mockCleara 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:
() => MockInstanceFunguje jako
mockReseta 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) => MockInstancePř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) => MockInstancePř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:
() => MockInstanceNastaví vnitřní implementaci tak, aby vracela kontext
this.
mockReturnValue
Typ:
(value: any) => MockInstancePř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) => MockInstancePř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ímockImplementationnebo 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;