Étendre les Matchers
Vitest étant compatible avec Chai et Jest, vous avez la possibilité d'utiliser l'API chai.use
ou expect.extend
, selon votre préférence.
Ce guide se concentre sur l'extension des matchers via expect.extend
. Pour l'API de Chai, veuillez consulter leur guide.
Pour étendre les matchers par défaut, appelez expect.extend
en lui passant un objet contenant vos matchers personnalisés.
expect.extend({
toBeFoo(received, expected) {
const { isNot } = this;
return {
// Ne modifiez pas la propriété `pass` en fonction de `isNot`. Vitest gère cela automatiquement.
pass: received === 'foo',
message: () => `${received} is${isNot ? ' not' : ''} foo`,
};
},
});
Si vous utilisez TypeScript, vous pouvez étendre l'interface Assertion
par défaut dans un fichier de déclaration global (par exemple : vitest.d.ts
) avec le code ci-dessous :
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
Depuis Vitest 3.2, vous pouvez étendre l'interface Matchers
pour bénéficier d'assertions typées de manière sûre dans les méthodes expect.extend
, expect().*
et expect.*
simultanément. Auparavant, il était nécessaire de définir des interfaces distinctes pour chacune de ces méthodes.
WARNING
Assurez-vous d'inclure le fichier de déclaration global dans votre tsconfig.json
.
La valeur de retour d'un matcher doit être compatible avec l'interface suivante :
interface ExpectationResult {
pass: boolean;
message: () => string;
// Si ces propriétés sont fournies, elles apparaîtront automatiquement dans un diff
// en cas d'échec du matcher, vous n'avez donc pas besoin d'afficher le diff manuellement.
actual?: unknown;
expected?: unknown;
}
WARNING
Si vous créez un matcher asynchrone, n'oubliez pas d'utiliser await
pour le résultat (await expect('foo').toBeFoo()
) dans le test lui-même :
expect.extend({
async toBeAsyncAssertion() {
// ...
},
});
await expect().toBeAsyncAssertion();
Le premier argument de la fonction d'un matcher est la valeur reçue (celle passée à expect(received)
). Les arguments suivants sont transmis directement au matcher.
La fonction de matcher a accès au contexte this
qui contient les propriétés suivantes :
isNot
Renvoie true
si le matcher a été appelé avec le modificateur not
(expect(received).not.toBeFoo()
).
promise
Si le matcher a été appelé avec les modificateurs resolved
ou rejected
, cette valeur contiendra le nom du modificateur. Sinon, il s'agira d'une chaîne vide.
equals
Il s'agit d'une fonction utilitaire qui permet de comparer deux valeurs. Elle renvoie true
si les valeurs sont égales, false
sinon. Cette fonction est utilisée en interne par presque tous les matchers et prend en charge les objets avec des matchers asymétriques par défaut.
utils
Contient un ensemble de fonctions utilitaires que vous pouvez utiliser pour formater les messages.
Le contexte this
contient également des informations sur le test en cours. Vous pouvez également les obtenir en appelant expect.getState()
. Les propriétés les plus utiles sont :
currentTestName
Nom complet du test actuel (incluant le bloc describe
).
testPath
Chemin d'accès au fichier de test actuel.