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.