Estendendo Matchers
Como o Vitest é compatível com Chai e Jest, você pode usar a API chai.use
ou expect.extend
, a que você preferir.
Este guia explorará a extensão de matchers com expect.extend
. Se você estiver interessado na API do Chai, consulte o guia deles.
Para estender os matchers padrão, chame expect.extend
com um objeto contendo seus matchers personalizados.
expect.extend({
toBeFoo(received, expected) {
const { isNot } = this;
return {
// Não altere o seu "pass" com base em isNot, pois o Vitest faz isso por você.
pass: received === 'foo',
message: () => `${received} is${isNot ? ' not' : ''} foo`,
};
},
});
Se você estiver usando TypeScript, pode estender a interface padrão de Assertion
em um arquivo de declaração de ambiente (por exemplo: vitest.d.ts
) com o código abaixo:
import 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: () => R;
}
declare module 'vitest' {
interface Matchers<T = any> extends CustomMatchers<T> {}
}
import 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: () => R;
}
declare module 'vitest' {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
}
TIP
Desde o Vitest 3.2, é possível estender a interface Matchers
para ter asserções com segurança de tipo em expect.extend
, expect().*
e expect.*
simultaneamente. Anteriormente, era necessário definir interfaces separadas para cada uma delas.
WARNING
Não se esqueça de incluir o arquivo de declaração de ambiente no seu tsconfig.json
.
O valor de retorno de um matcher deve ser compatível com a seguinte interface:
interface ExpectationResult {
pass: boolean;
message: () => string;
// Se você os passar, eles aparecerão automaticamente dentro de um diff quando
// o matcher não passar, então você não precisará imprimir o diff por conta própria
actual?: unknown;
expected?: unknown;
}
WARNING
Se você criar um matcher assíncrono, não se esqueça de usar await
ao obter o resultado (await expect('foo').toBeFoo()
) no próprio teste:
expect.extend({
async toBeAsyncAssertion() {
// ...
},
});
await expect().toBeAsyncAssertion();
O primeiro argumento dentro da função de um matcher é o valor recebido (o valor passado em expect(received)
). Os demais são argumentos passados diretamente para o matcher.
A função do matcher tem acesso ao contexto this
com as seguintes propriedades:
isNot
Retorna true
se o matcher foi chamado com not
(expect(received).not.toBeFoo()
).
promise
Se o matcher foi chamado com resolved
/rejected
, este valor conterá o nome do modificador. Caso contrário, será uma string vazia.
equals
Esta é uma função utilitária que permite comparar dois valores. Ela retornará true
se os valores forem iguais, e false
caso contrário. Esta função é usada internamente para quase todos os matchers e suporta objetos com matchers assimétricos por padrão.
utils
Contém um conjunto de funções utilitárias que podem ser usadas para exibir mensagens.
O contexto this
também contém informações sobre o teste atual. Você também pode obtê-lo chamando expect.getState()
. As propriedades mais úteis são:
currentTestName
Nome completo do teste atual (incluindo o bloco describe
).
testPath
Caminho do arquivo do teste atual.