Funciones Mock
Puedes crear una función mock para rastrear su ejecución con el método vi.fn
. Si quieres rastrear un método en un objeto ya creado, puedes usar el método 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;
Deberías usar aserciones de espionaje (p. ej., toHaveBeenCalled
) en expect
para verificar el resultado del espía. Esta referencia de la API describe las propiedades y métodos disponibles para manipular el comportamiento del espía.
getMockName
Tipo:
() => string
Úsalo para devolver el nombre asignado al mock con el método
.mockName(name)
.
mockClear
Tipo:
() => MockInstance
Borra toda la información registrada de cada llamada. Después de invocarlo,
spy.mock.calls
yspy.mock.results
devolverán arrays vacíos. Es útil si deseas restablecer completamente un mock a su estado inicial.Si quieres que este método se invoque automáticamente antes de cada test, puedes habilitar la configuración
clearMocks
en la configuración.
mockName
Tipo:
(name: string) => MockInstance
Establece el nombre interno del mock. Útil para identificar qué mock falló en la aserción.
mockImplementation
Tipo:
(fn: Function) => MockInstance
Recibe una función que se utilizará como la implementación del mock.
Por ejemplo:
tsconst mockFn = vi.fn().mockImplementation(apples => apples + 1); // o: 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
Tipo:
(fn: Function) => MockInstance
Acepta una función que se usará como la implementación del mock para una única llamada a la función mockeada. Puede ser encadenado para que múltiples llamadas a la función produzcan diferentes resultados.
tsconst myMockFn = vi .fn() .mockImplementationOnce(() => true) .mockImplementationOnce(() => false); myMockFn(); // true myMockFn(); // false
Cuando la función simulada se queda sin implementaciones específicas, invocará la implementación por defecto que se haya establecido con
vi.fn(() => defaultValue)
o.mockImplementation(() => defaultValue)
.tsconst myMockFn = vi .fn(() => 'default') .mockImplementationOnce(() => 'first call') .mockImplementationOnce(() => 'second call'); // 'first call', 'second call', 'default', 'default' console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
withImplementation
Tipo:
(fn: Function, callback: () => void) => MockInstance
Tipo:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
Reemplaza temporalmente la implementación original del mock mientras el callback está siendo ejecutado.
jsconst myMockFn = vi.fn(() => 'original'); myMockFn.withImplementation( () => 'temp', () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original'
Puede ser usado con un callback asíncrono. Se debe esperar a que el callback termine su ejecución para poder usar la implementación original.
tstest('async callback', () => { const myMockFn = vi.fn(() => 'original'); // Esperamos esta llamada ya que el callback es asíncrono await myMockFn.withImplementation( () => 'temp', async () => { myMockFn(); // 'temp' } ); myMockFn(); // 'original' });
Además, tiene precedencia sobre
mockImplementationOnce
.
mockRejectedValue
Tipo:
(value: any) => MockInstance
Acepta un valor que se rechazará cuando se llame a la función asíncrona.
tsconst asyncMock = vi.fn().mockRejectedValue(new Error('Async error')); await asyncMock(); // arroja "Async error"
mockRejectedValueOnce
Tipo:
(value: any) => MockInstance
Acepta un valor que será rechazado para una única llamada a la función mock. Si es encadenado, cada llamada consecutiva rechazará el valor pasado.
tsconst asyncMock = vi .fn() .mockResolvedValueOnce('first call') .mockRejectedValueOnce(new Error('Async error')); await asyncMock(); // first call await asyncMock(); // arroja "Async error"
mockReset
Tipo:
() => MockInstance
Realiza la misma acción que
mockClear
y reemplaza la implementación interna con una función vacía (retornandoundefined
cuando es invocada). Esto es útil si deseas restablecer completamente un mock a su estado inicial.Si quieres que este método se invoque automáticamente antes de cada test, puedes habilitar la configuración
mockReset
en la configuración.
mockRestore
Tipo:
() => MockInstance
Hace lo que
mockReset
hace y restaura la implementación interna a la función original.Es importante tener en cuenta que restaurar un mock creado con
vi.fn()
reemplazará su implementación con una función vacía que retornaundefined
. Restaurar unvi.fn(impl)
restaurará la implementación aimpl
.Si quieres que este método se invoque automáticamente antes de cada test, puedes habilitar la configuración
restoreMocks
en la configuración.
mockResolvedValue
Tipo:
(value: any) => MockInstance
Acepta un valor que se resolverá cuando la función asíncrona sea llamada.
tsconst asyncMock = vi.fn().mockResolvedValue(43); await asyncMock(); // 43
mockResolvedValueOnce
Tipo:
(value: any) => MockInstance
Acepta un valor que se resolverá para una única llamada a la función mock. Si es encadenado, cada llamada consecutiva resolverá el valor pasado.
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
Tipo:
() => MockInstance
Establece la implementación interna para retornar el contexto
this
.
mockReturnValue
Tipo:
(value: any) => MockInstance
Acepta un valor que se retornará cada vez que la función mock sea llamada.
tsconst mock = vi.fn(); mock.mockReturnValue(42); mock(); // 42 mock.mockReturnValue(43); mock(); // 43
mockReturnValueOnce
Tipo:
(value: any) => MockInstance
Acepta un valor que se retornará para una única llamada a la función mock. Si es encadenado, cada llamada consecutiva retornará el valor pasado. Cuando no hay más valores
mockReturnValueOnce
para usar, se llama a la función especificada pormockImplementation
u otros métodosmockReturn*
.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
Este es un array que contiene todos los argumentos para cada llamada. Cada elemento del array representa los argumentos de una llamada específica.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3', 'arg4');
fn.mock.calls ===
[
['arg1', 'arg2'], // primera llamada
['arg3', 'arg4'], // segunda llamada
];
mock.lastCall
Contiene los argumentos de la última invocación. Si el espía no fue llamado, retornará undefined
.
mock.results
Este es un array que contiene todos los valores que fueron devueltos por la función. Cada elemento del array es un objeto con las propiedades type
y value
. Los tipos disponibles son:
'return'
- la función retornó sin lanzar una excepción.'throw'
- la función lanzó una excepción.
La propiedad value
contiene el valor devuelto o el error lanzado. Si la función retornó una promesa, cuando se resuelva, la propiedad value
contendrá el valor al que se resolvió la promesa.
const fn = vi.fn();
const result = fn(); // retornó 'result'
try {
fn(); // lanzó Error
} catch {}
fn.mock.results ===
[
// primer resultado
{
type: 'return',
value: 'result',
},
// último resultado
{
type: 'throw',
value: Error,
},
];
mock.instances
Este es un array que contiene todas las instancias que fueron instanciadas cuando el mock fue llamado con la palabra clave new
. Es importante tener en cuenta que esto representa el contexto (this
) de la función, y no el valor que retorna.
WARNING
Si el mock fue instanciado con new MyClass()
, entonces mock.instances
será un array con un valor:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Si devuelves un valor en el constructor, no estará en el array instances
, sino que estará en results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;