Funkcje Mockujące
Możesz utworzyć funkcję mock, aby śledzić jej wywołania, używając metody vi.fn
. Jeśli chcesz śledzić metodę istniejącego obiektu, użyj metody 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;
Używaj asercji szpiegujących (np. toHaveBeenCalled
) w połączeniu z expect
, aby sprawdzić, czy szpieg został wywołany zgodnie z oczekiwaniami. Ten dokument API opisuje dostępne właściwości i metody do manipulowania zachowaniem funkcji mock.
getMockName
Typ:
() => string
Zwraca nazwę nadaną funkcji mock za pomocą metody
.mockName(name)
.
mockClear
Typ:
() => MockInstance
Czyści informacje o wszystkich wywołaniach funkcji. Po wywołaniu tej metody,
spy.mock.calls
ispy.mock.results
będą zwracać puste tablice. Jest to przydatne, gdy chcesz wyczyścić funkcję mock między asercjami.Jeśli chcesz, aby ta metoda była wywoływana automatycznie przed każdym testem, włącz opcję
clearMocks
w konfiguracji.
mockName
Typ:
(name: string) => MockInstance
Ustawia wewnętrzną nazwę funkcji mock. Pomaga to zidentyfikować funkcję mock, która nie spełniła asercji.
mockImplementation
Typ:
(fn: Function) => MockInstance
Akceptuje funkcję, która będzie używana jako implementacja funkcji mock.
Na przykład:
tsconst mockFn = vi.fn().mockImplementation(apples => apples + 1); // lub: const mockFn = 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
Akceptuje funkcję, która będzie używana jako implementacja funkcji mock tylko dla jednego wywołania. Można ją łączyć łańcuchowo, aby kolejne wywołania funkcji zwracały różne wyniki.
tsconst myMockFn = vi .fn() .mockImplementationOnce(() => true) .mockImplementationOnce(() => false); myMockFn(); // true myMockFn(); // false
Gdy funkcja mock nie ma już zdefiniowanej implementacji
Once
, zostanie wywołana implementacja domyślna, ustawiona za pomocąvi.fn(() => defaultValue)
lub.mockImplementation(() => defaultValue)
, jeśli zostały one zdefiniowane: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>
Tymczasowo zastępuje oryginalną implementację funkcji mock podczas wykonywania funkcji zwrotnej (callback).
jsconst myMockFn = vi.fn(() => 'original'); myMockFn.withImplementation( () => 'temp', () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original'
Może być używana z asynchroniczną funkcją zwrotną. Należy poczekać na zakończenie metody, aby przywrócić oryginalną implementację.
tstest('async callback', () => { const myMockFn = vi.fn(() => 'original'); // Oczekujemy na to wywołanie, ponieważ funkcja zwrotna jest asynchroniczna await myMockFn.withImplementation( () => 'temp', async () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original' });
Ponadto, ta metoda ma pierwszeństwo przed
mockImplementationOnce
.
mockRejectedValue
Typ:
(value: any) => MockInstance
Akceptuje wartość, która posłuży jako odrzucona wartość obietnicy, gdy zostanie wywołana funkcja asynchroniczna.
tsconst asyncMock = vi.fn().mockRejectedValue(new Error('Async error')); await asyncMock(); // rzuca błąd "Async error"
mockRejectedValueOnce
Typ:
(value: any) => MockInstance
Akceptuje wartość, która zostanie odrzucona dla jednego wywołania funkcji mock. Przy łańcuchowym wywoływaniu, każde kolejne wywołanie odrzuci przekazaną wartość.
tsconst asyncMock = vi .fn() .mockResolvedValueOnce('first call') .mockRejectedValueOnce(new Error('Async error')); await asyncMock(); // first call await asyncMock(); // rzuca błąd "Async error"
mockReset
Typ:
() => MockInstance
Działa jak
mockClear
, a dodatkowo wewnętrzna implementacja staje się pustą funkcją (zwracającąundefined
, gdy zostanie wywołana). Jest to przydatne, gdy chcesz całkowicie zresetować funkcję mock do jej początkowego stanu.Jeśli chcesz, aby ta metoda była wywoływana automatycznie przed każdym testem, włącz opcję
mockReset
w konfiguracji.
mockRestore
Typ:
() => MockInstance
Działa jak
mockReset
, a dodatkowo przywraca wewnętrzną implementację do oryginalnej funkcji.Zauważ, że przywrócenie funkcji mock utworzonej za pomocą
vi.fn()
ustawi implementację na pustą funkcję, która zwracaundefined
. Przywrócenievi.fn(impl)
przywróci implementację doimpl
.Jeśli chcesz, aby ta metoda była wywoływana automatycznie przed każdym testem, włącz opcję
restoreMocks
w konfiguracji.
mockResolvedValue
Typ:
(value: any) => MockInstance
Akceptuje wartość, która posłuży jako pomyślny wynik obietnicy, gdy zostanie wywołana funkcja asynchroniczna.
tsconst asyncMock = vi.fn().mockResolvedValue(43); await asyncMock(); // 43
mockResolvedValueOnce
Typ:
(value: any) => MockInstance
Akceptuje wartość, która zostanie rozwiązana dla jednego wywołania funkcji mock. Przy łańcuchowym wywoływaniu, każde kolejne wywołanie zwróci przekazaną wartość jako pomyślny wynik obietnicy.
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
Ustawia wewnętrzną implementację, aby zwracała kontekst
this
.
mockReturnValue
Typ:
(value: any) => MockInstance
Akceptuje wartość, która będzie zwracana za każdym razem, gdy funkcja mock zostanie wywołana.
tsconst mock = vi.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
mockReturnValueOnce
Typ:
(value: any) => MockInstance
Akceptuje wartość, która będzie zwracana dla jednego wywołania funkcji mock. Jeśli jest połączona łańcuchowo, każde kolejne wywołanie zwróci przekazaną wartość. Gdy nie ma już więcej wartości
mockReturnValueOnce
do użycia, wywoływana jest funkcja określona przezmockImplementation
lub inne metodymockReturn*
.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
Jest to tablica zawierająca argumenty przekazane do każdego wywołania funkcji mock. Każdy element tablicy reprezentuje argumenty pojedynczego wywołania.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3', 'arg4');
fn.mock.calls ===
[
['arg1', 'arg2'], // pierwsze wywołanie
['arg3', 'arg4'], // drugie wywołanie
];
mock.lastCall
Zawiera argumenty ostatniego wywołania funkcji mock. Jeśli funkcja mock nie została wywołana, zwróci undefined
.
mock.results
Jest to tablica zawierająca informacje o wszystkich wynikach wywołań funkcji mock. Jeden element tablicy to obiekt z właściwościami type
i value
. Dostępne typy to:
'return'
- funkcja zwróciła wartość bez rzucania wyjątku.'throw'
- funkcja rzuciła wyjątek.
Właściwość value
zawiera zwróconą wartość lub rzucony błąd. Jeśli funkcja zwróciła obietnicę, po jej rozwiązaniu właściwość value
będzie zawierała wartość, do której obietnica została rozwiązana.
const fn = vi.fn();
const result = fn(); // zwrócona wartość to 'result'
try {
fn(); // rzucony został błąd Error
} catch {}
fn.mock.results ===
[
// pierwszy wynik
{
type: 'return',
value: 'result',
},
// ostatni wynik
{
type: 'throw',
value: Error,
},
];
mock.instances
Jest to tablica zawierająca wszystkie instancje, które zostały utworzone, gdy funkcja mock została wywołana za pomocą słowa kluczowego new
. Należy pamiętać, że jest to rzeczywisty kontekst (this
) funkcji, a nie wartość, którą funkcja zwraca.
WARNING
Jeśli funkcja mock została utworzona za pomocą operatora new
na klasie MyClass
, to mock.instances
będzie tablicą zawierającą jedną instancję:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Jeśli konstruktor zwraca wartość (inną niż instancja klasy), to nie będzie ona przechowywana w tablicy instances
, lecz w tablicy results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;