Funções Mock
Você pode criar uma função mock para rastrear sua execução usando o método vi.fn
. Se você deseja rastrear um método de um objeto já existente, você pode usar o 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;
Você deve usar asserções de mock (por exemplo, toHaveBeenCalled
) em expect
para verificar o resultado do mock. Esta referência de API descreve as propriedades e métodos disponíveis para manipular o comportamento do mock.
getMockImplementation
- Tipo:
(...args: any) => any
Retorna a implementação mock atual, se houver.
Se o mock foi criado com vi.fn
, ele considerará a função passada como a implementação mock.
Se o mock foi criado com vi.spyOn
, ele retornará undefined
a menos que uma implementação personalizada tenha sido fornecida.
getMockName
- Tipo:
() => string
Use isso para retornar o nome atribuído ao mock com o método .mockName(name)
.
mockClear
- Tipo:
() => MockInstance
Limpa todas as informações de cada chamada. Após chamá-lo, todas as propriedades de .mock
retornarão a um estado vazio. Este método não redefine as implementações. É útil se você precisar limpar o mock entre diferentes asserções.
Se você deseja que este método seja chamado automaticamente antes de cada teste, você pode habilitar a configuração clearMocks
na configuração.
mockName
- Tipo:
(name: string) => MockInstance
Define o nome interno do mock. Útil para visualizar o nome do mock se a asserção falhar.
mockImplementation
- Tipo:
(fn: Function) => MockInstance
Aceita uma função que será usada como a implementação do 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
- Tipo:
(fn: Function) => MockInstance
Aceita uma função que será usada como a implementação do mock durante a próxima chamada. Pode ser encadeado, permitindo que chamadas consecutivas produzam resultados diferentes.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
.fn()
.mockImplementationOnce(() => true)
.mockImplementationOnce(() => false);
myMockFn(); // true
myMockFn(); // false
Quando a função mock ficar sem implementações, ela invocará a implementação padrão que foi definida anteriormente com vi.fn(() => defaultValue)
ou .mockImplementation(() => defaultValue)
, caso tenham sido chamadas:
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
- Tipo:
(fn: Function, callback: () => void) => MockInstance
- Tipo:
(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>
Substitui temporariamente a implementação mock original enquanto o callback está sendo executado.
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');
myMockFn.withImplementation(
() => 'temp',
() => {
myMockFn(); // 'temp'
}
);
myMockFn(); // 'original'
Pode ser usado com um callback assíncrono. O método deve ser aguardado para usar a implementação original posteriormente.
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'
});
Note que este método tem precedência sobre o mockImplementationOnce
.
mockRejectedValue
- Tipo:
(value: any) => MockInstance
Aceita um erro que será rejeitado quando a função assíncrona for invocada.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
await asyncMock(); // throws "Async error"
mockRejectedValueOnce
- Tipo:
(value: any) => MockInstance
Aceita um valor que será rejeitado durante a próxima chamada de função. Se encadeado, cada chamada consecutiva rejeitará o valor especificado.
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
- Tipo:
() => MockInstance
Executa as mesmas ações de mockClear
e redefine a implementação interna para uma função vazia (retornando undefined
quando invocada). Isso também redefine todas as implementações "Once". Isso é útil quando você deseja redefinir completamente um mock para o estado padrão.
Se você deseja que este método seja chamado automaticamente antes de cada teste, você pode habilitar a configuração mockReset
na configuração.
mockRestore
- Tipo:
() => MockInstance
Faz o que mockReset
faz e restaura a implementação interna à função original.
Observe que restaurar o mock de vi.fn()
definirá a implementação como uma função vazia que retorna undefined
. Restaurar um vi.fn(impl)
restaurará a implementação para impl
.
Se você deseja que este método seja chamado automaticamente antes de cada teste, você pode habilitar a configuração restoreMocks
na configuração.
mockResolvedValue
- Tipo:
(value: any) => MockInstance
Aceita um valor que será resolvido quando a função assíncrona for invocada.
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);
await asyncMock(); // 42
mockResolvedValueOnce
- Tipo:
(value: any) => MockInstance
Aceita um valor que será resolvido durante a próxima chamada de função. Se encadeado, cada chamada consecutiva resolverá o valor especificado.
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
- Tipo:
() => MockInstance
Use isso se você precisar retornar o contexto this
do método sem invocar a implementação original. Esta é uma abreviação para:
spy.mockImplementation(function () {
return this;
});
mockReturnValue
- Tipo:
(value: any) => MockInstance
Aceita um valor que será retornado sempre que a função mock for invocada.
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43
mockReturnValueOnce
- Tipo:
(value: any) => MockInstance
Aceita um valor que será retornado durante a próxima chamada de função. Se encadeado, cada chamada consecutiva retornará o valor especificado.
Quando não houver mais valores mockReturnValueOnce
para usar, o mock recorrerá à implementação definida anteriormente, se houver.
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
Este é um array contendo todos os argumentos para cada chamada. Um item do array contém os argumentos dessa chamada.
const fn = vi.fn();
fn('arg1', 'arg2');
fn('arg3');
fn.mock.calls ===
[
['arg1', 'arg2'], // first call
['arg3'], // second call
];
mock.lastCall
Isso contém os argumentos da última chamada. Se o mock não tiver sido chamado, retornará undefined
.
mock.results
Este é um array contendo todos os valores que foram retornados (returned
) pela função. Um item do array é um objeto com as propriedades type
e value
. Os tipos disponíveis são:
'return'
- função que retornou sem lançar erro.'throw'
- função que lançou um erro.
A propriedade value
contém o valor retornado ou o erro lançado. Se a função retornou uma promise, o value
será o valor resolvido, não a Promise
real, a menos que nunca tenha sido resolvida.
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
A ordem de execução do mock. Isso retorna um array de números que são compartilhados por todos os mocks definidos.
const fn1 = vi.fn();
const fn2 = vi.fn();
fn1();
fn2();
fn1();
fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];
mock.instances
Este é um array contendo todas as instâncias que foram instanciadas quando o mock foi chamado com a palavra-chave new
. Note que este é o contexto real (this
) da função, e não um valor de retorno.
WARNING
Se o mock foi instanciado com new MyClass()
, então mock.instances
será um array com um valor:
const MyClass = vi.fn();
const a = new MyClass();
MyClass.mock.instances[0] === a;
Se você retornar um valor do construtor, ele não estará no array instances
, mas sim em results
:
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();
Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;