Funzioni Mock
Puoi creare una funzione mock per monitorare la sua esecuzione con il metodo vi.fn
. Se desideri tracciare un metodo su un oggetto esistente, puoi utilizzare il metodo 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;
Dovresti utilizzare le asserzioni mock (ad esempio, toHaveBeenCalled
) su expect
per verificare il risultato del mock. Questa documentazione API descrive le proprietà e i metodi disponibili per gestire il comportamento del mock.
TIP
L'implementazione della funzione personalizzata nei tipi seguenti è contrassegnata con il generico <T>
.
getMockImplementation
function getMockImplementation(): T | undefined;
Restituisce l'implementazione mock corrente, se presente.
Se il mock è stato creato con vi.fn
, utilizzerà la funzione fornita come implementazione mock.
Se il mock è stato creato con vi.spyOn
, restituirà undefined
se non viene fornita un'implementazione personalizzata.
getMockName
function getMockName(): string;
Utilizza questo metodo per restituire il nome assegnato al mock con il metodo .mockName(name)
. Per impostazione predefinita, restituirà vi.fn()
.
mockClear
function mockClear(): MockInstance<T>;
Cancella tutte le informazioni relative a ogni chiamata. Dopo averlo chiamato, tutte le proprietà su .mock
torneranno al loro stato originale. Questo metodo non reimposta le implementazioni. È utile per pulire i mock tra diverse asserzioni.
Per chiamare automaticamente questo metodo prima di ogni test, abilita l'impostazione clearMocks
nella configurazione.
mockName
function mockName(name: string): MockInstance<T>;
Imposta il nome interno del mock. Questo è utile per identificare il mock quando un test fallisce.
mockImplementation
function mockImplementation(fn: T): MockInstance<T>;
Accetta una funzione da utilizzare come implementazione mock. TypeScript si aspetta che gli argomenti e il tipo di ritorno corrispondano a quelli della funzione originale.
const mockFn = vi.fn().mockImplementation((apples: number) => apples + 1);
// or: 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>;
Accetta una funzione da usare come implementazione mock. TypeScript si aspetta che gli argomenti e il tipo di ritorno corrispondano a quelli della funzione originale. Questo metodo può essere concatenato per produrre risultati diversi per chiamate di funzione multiple.
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true) // 1st call
.mockImplementationOnce(() => false); // 2nd call
myMockFn(); // 1st call: true
myMockFn(); // 2nd call: false
Quando la funzione mock ha esaurito le implementazioni specifiche, invocherà l'implementazione predefinita impostata con vi.fn(() => defaultValue)
o .mockImplementation(() => defaultValue)
se sono state chiamate:
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>>;
Sostituisce temporaneamente l'implementazione mock originale mentre il callback è in esecuzione.
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Può essere usato con un callback asincrono. Il metodo deve essere atteso per usare l'implementazione originale in seguito.
test('async callback', () => {
const myMockFn = vi.fn(() => 'original');
// We await this call since the callback is async
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
Nota che questo metodo ha priorità su mockImplementationOnce
.
mockRejectedValue
function mockRejectedValue(value: unknown): MockInstance<T>;
Accetta un valore che verrà restituito come errore quando viene chiamata la funzione asincrona.
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws Error<'Async error'>
mockRejectedValueOnce
function mockRejectedValueOnce(value: unknown): MockInstance<T>;
Accetta un valore che verrà rifiutato durante la prossima chiamata di funzione. Se concatenato, ogni chiamata successiva rifiuterà il valore specificato.
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // 'first call'
await asyncMock(); // throws Error<'Async error'>
mockReset
function mockReset(): MockInstance<T>;
Esegue le stesse operazioni di mockClear
e imposta l'implementazione interna su una funzione vuota (che restituisce undefined
quando invocata). Questo reimposta anche tutte le implementazioni "once". È utile per ripristinare completamente un mock al suo stato predefinito.
Per chiamare automaticamente questo metodo prima di ogni test, abilita l'impostazione mockReset
nella configurazione.
mockRestore
function mockRestore(): MockInstance<T>;
Esegue le stesse azioni di mockReset
e ripristina l'implementazione interna alla funzione originale.
Nota che il ripristino di un mock creato con vi.fn()
imposterà l'implementazione su una funzione vuota che restituisce undefined
. Il ripristino di un mock creato con vi.fn(impl)
ripristinerà l'implementazione a impl
.
Per chiamare automaticamente questo metodo prima di ogni test, abilita l'impostazione restoreMocks
nella configurazione.
mockResolvedValue
function mockResolvedValue(value: Awaited<ReturnType<T>>): MockInstance<T>;
Accetta un valore che verrà risolto quando viene chiamata la funzione asincrona. TypeScript accetterà solo valori che corrispondono al tipo di ritorno della funzione originale.
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
function mockResolvedValueOnce(value: Awaited<ReturnType<T>>): MockInstance<T>;
Accetta un valore che verrà risolto durante la prossima chiamata di funzione. TypeScript accetterà solo valori che corrispondono al tipo di ritorno della funzione originale. Se concatenato, ogni chiamata consecutiva risolverà il valore specificato.
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>;
Utilizza questo metodo se hai bisogno di restituire il contesto this
del metodo senza invocare l'implementazione effettiva. Questa è una scorciatoia per:
spy.mockImplementation(function () {
return this;
});
mockReturnValue
function mockReturnValue(value: ReturnType<T>): MockInstance<T>;
Accetta un valore che sarà restituito ogni volta che viene chiamata la funzione mock. TypeScript accetterà solo valori che corrispondono al tipo di ritorno della funzione originale.
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
function mockReturnValueOnce(value: ReturnType<T>): MockInstance<T>;
Accetta un valore che verrà restituito ogni volta che viene chiamata la funzione mock. TypeScript accetterà solo valori che corrispondono al tipo di ritorno della funzione originale.
Quando la funzione mock esaurisce le implementazioni, invocherà l'implementazione predefinita impostata con vi.fn(() => defaultValue)
o .mockImplementation(() => defaultValue)
se sono state chiamate:
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>[];
Questo è un array contenente tutti gli argomenti per ogni chiamata. Ogni elemento dell'array rappresenta gli argomenti di una singola chiamata.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call
['arg3'], // second call
];
mock.lastCall
const lastCall: Parameters<T> | undefined;
Questo contiene gli argomenti dell'ultima chiamata. Se il mock non è stato chiamato, restituirà undefined
.
mock.results
interface MockResultReturn<T> {
type: 'return';
/**
* The value that was returned from the function.
* If function returned a Promise, then this will be a resolved value.
*/
value: T;
}
interface MockResultIncomplete {
type: 'incomplete';
value: undefined;
}
interface MockResultThrow {
type: 'throw';
/**
* An error that was thrown during function execution.
*/
value: any;
}
type MockResult<T> =
| MockResultReturn<T>
| MockResultThrow
| MockResultIncomplete;
const results: MockResult<ReturnType<T>>[];
Questo è un array contenente i risultati di tutte le chiamate alla funzione. Ogni elemento dell'array è un oggetto con le proprietà type
e value
. I tipi disponibili sono:
'return'
- la funzione è terminata senza lanciare eccezioni.'throw'
- la funzione ha lanciato un valore.
La proprietà value
contiene il valore restituito o l'errore lanciato. Se la funzione ha restituito una Promise
, allora result
sarà sempre 'return'
anche se la promise è stata rifiutata.
const fn = vi
.fn()
.mockReturnValueOnce('result')
.mockImplementationOnce(() => {
throw new Error('thrown error');
});
const result = fn(); // returned 'result'
try {
fn(); // threw Error
} catch {}
fn.mock.results ===
[
// first result
{
type: 'return',
value: 'result',
},
// last result
{
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>>>[];
Un array contenente i risultati di tutte le chiamate alla funzione che sono state risolte
o rifiutate
.
Questo array sarà vuoto se la funzione non è mai stata risolta o rifiutata.
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[];
Questa proprietà restituisce l'ordine di esecuzione della funzione mock. È un array di numeri che sono condivisi tra tutti i mock definiti.
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>[];
Questa proprietà è un array dei valori this
usati durante ogni chiamata alla funzione mock.
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>[];
Questa proprietà è un array contenente tutte le istanze che sono state create quando il mock è stato chiamato con la parola chiave new
. Si noti che questo è l'effettivo contesto (this
) della funzione, non un valore di ritorno.
WARNING
Se il mock è stato istanziato con new MyClass()
, allora mock.instances
sarà un array con un valore:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Se viene restituito un valore dal costruttore, non sarà nell'array instances
, ma invece all'interno di results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;