Fonctions Mock
Vous pouvez créer une fonction mock pour suivre son exécution à l'aide de la méthode vi.fn
. Si vous souhaitez surveiller une méthode sur un objet existant, vous pouvez utiliser 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;
Utilisez les assertions de mock (par exemple, toHaveBeenCalled
) sur expect
pour vérifier le comportement du mock. Cette documentation d'API décrit les propriétés et méthodes disponibles pour manipuler le comportement du mock.
getMockImplementation
- Type:
(...args: any) => any
Renvoie l'implémentation actuelle du mock, si elle existe.
Si le mock a été créé avec vi.fn
, la fonction transmise est considérée comme l'implémentation du mock.
Si le mock a été créé avec vi.spyOn
, la valeur retournée est undefined
sauf si une implémentation personnalisée est fournie.
getMockName
- Type:
() => string
Utilisez cette méthode pour obtenir le nom attribué au mock avec .mockName(name)
.
mockClear
- Type:
() => MockInstance
Efface toutes les informations concernant chaque appel. Après son appel, toutes les propriétés de .mock
retourneront un état initial. Cette méthode ne réinitialise pas les implémentations existantes. Elle est utile pour réinitialiser le mock entre différentes assertions.
Si vous souhaitez que cette méthode soit appelée automatiquement avant chaque test, vous pouvez activer le paramètre clearMocks
dans la configuration.
mockName
- Type:
(name: string) => MockInstance
Définit le nom interne du mock. Utile pour identifier le mock en cas d'échec d'une assertion.
mockImplementation
- Type:
(fn: Function) => MockInstance
Accepte une fonction qui sera utilisée comme implémentation du mock.
import { vi } from 'vitest';
// ---cut---
const mockFn = vi.fn().mockImplementation(apples => 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
- Type:
(fn: Function) => MockInstance
Accepte une fonction qui sera utilisée comme implémentation du mock lors du prochain appel. Elle peut être chaînée pour que plusieurs appels produisent des résultats différents.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true)
.mockImplementationOnce(() => false);
myMockFn(); // true
myMockFn(); // false
Lorsque la fonction mock n'a plus d'implémentations définies avec mockImplementationOnce
, elle invoque l'implémentation par défaut définie avec vi.fn(() => defaultValue)
ou .mockImplementation(() => defaultValue)
, si elle existe.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn(() => 'default')
.mockImplementationOnce(() => 'first call')
.mockImplementationOnce(() => 'second call');
// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
withImplementation
- Type:
(fn: Function, callback: () => void) => MockInstance
- Type:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
Remplace temporairement l'implémentation du mock par une nouvelle implémentation pendant l'exécution du callback.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Peut être utilisé avec un callback asynchrone. L'implémentation originale est restaurée après la résolution de la promesse retournée par le callback.
test('async callback', () => {
const myMockFn = vi.fn(() => 'original');
// On attend la résolution de la promesse car le callback est asynchrone
await myMockFn.withImplementation(
() => 'temp',
async () => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
});
Notez que cette méthode a la priorité sur mockImplementationOnce
.
mockRejectedValue
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera rejetée lors de l'appel de la fonction asynchrone.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
mockRejectedValueOnce
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera rejetée lors du prochain appel de la fonction. Si elle est chaînée, chaque appel consécutif rejettera la valeur spécifiée.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
.fn()
.mockResolvedValueOnce('first call')
.mockRejectedValueOnce(new Error('Async error'));
await asyncMock(); // first call
await asyncMock(); // throws "Async error"
mockReset
- Type:
() => MockInstance
Effectue les mêmes actions que mockClear
et remplace l'implémentation interne par une fonction vide (retournant undefined
lors de son appel). Cela réinitialise également toutes les implémentations définies avec mockImplementationOnce
. Ceci est utile pour réinitialiser complètement un mock à son état par défaut.
Si vous souhaitez que cette méthode soit appelée automatiquement avant chaque test, vous pouvez activer le paramètre mockReset
dans la configuration.
mockRestore
- Type:
() => MockInstance
Effectue les mêmes actions que mockReset
et restaure l'implémentation interne à sa fonction originale.
Notez que la restauration d'un mock créé avec vi.fn()
définit l'implémentation à une fonction vide qui retourne undefined
. La restauration d'un mock créé avec vi.fn(impl)
restaurera l'implémentation à impl
.
Si vous souhaitez que cette méthode soit appelée automatiquement avant chaque test, vous pouvez activer le paramètre restoreMocks
dans la configuration.
mockResolvedValue
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera résolue lors de l'appel de la fonction asynchrone.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera résolue lors du prochain appel de la fonction. Si elle est chaînée, chaque appel consécutif résoudra la valeur spécifiée.
import { vi } from 'vitest';
// ---cut---
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
- Type:
() => MockInstance
Utilisez cette méthode si vous devez retourner le contexte this
sans invoquer l'implémentation réelle. C'est un raccourci pour :
spy.mockImplementation(function () {
return this;
});
mockReturnValue
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera retournée à chaque appel de la fonction mock.
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
- Type:
(value: any) => MockInstance
Accepte une valeur qui sera retournée lors du prochain appel de la fonction. Si elle est chaînée, chaque appel consécutif retournera la valeur spécifiée.
Lorsqu'il n'y a plus de valeurs mockReturnValueOnce
disponibles, le mock utilise l'implémentation précédemment définie, si elle existe.
import { vi } from 'vitest';
// ---cut---
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
C'est un tableau contenant tous les arguments de chaque appel. Chaque élément du tableau représente les arguments d'un appel.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call
['arg3'], // second call
];
mock.lastCall
Contient les arguments du dernier appel. Retourne undefined
si le mock n'a pas été appelé.
mock.results
C'est un tableau contenant toutes les valeurs retournées par la fonction. Chaque élément du tableau est un objet avec les propriétés type
et value
. Les types disponibles sont :
'return'
- la fonction s'est terminée sans exception.'throw'
- la fonction a levé une exception.
La propriété value
contient la valeur retournée ou l'erreur générée. Si la fonction a retourné une promesse, la value
sera la valeur résolue, pas la Promise
elle-même, à moins qu'elle n'ait jamais été résolue.
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.invocationCallOrder
Ordre d'exécution du mock. Retourne un tableau de nombres partagés entre tous les mocks définis.
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];
mock.instances
C'est un tableau contenant toutes les instances créées lorsque le mock a été appelé avec le mot-clé new
. Notez qu'il s'agit du contexte réel (this
) de la fonction, et non d'une valeur de retour.
WARNING
Si le mock a été instancié avec new MyClass()
, alors mock.instances
sera un tableau avec une seule valeur :
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Si vous retournez une valeur du constructeur, elle ne sera pas dans le tableau instances
, mais plutôt à l'intérieur de results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;