Estensione dei Matcher
Vitest è compatibile sia con Chai che con Jest, offrendo la flessibilità di utilizzare l'API chai.use
o expect.extend
a tua scelta.
Questa guida si concentrerà sull'estensione dei matcher tramite expect.extend
. Per informazioni sull'API di Chai, consulta la loro guida.
Per estendere i matcher predefiniti, invoca expect.extend
passando un oggetto contenente i tuoi matcher personalizzati.
expect.extend({
toBeFoo(received, expected) {
const { isNot } = this;
return {
// Non modificare il valore di "pass" in base a isNot. Vitest lo gestisce automaticamente.
pass: received === 'foo',
message: () => `${received} is${isNot ? ' not' : ''} foo`,
};
},
});
Se utilizzi TypeScript, puoi estendere l'interfaccia Assertion
predefinita in un file di dichiarazione globale (ad esempio: vitest.d.ts
) utilizzando il seguente codice:
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
A partire da Vitest 3.2, è possibile estendere l'interfaccia Matchers
per ottenere asserzioni con controllo dei tipi nei metodi expect.extend
, expect().*
e expect.*
contemporaneamente. In precedenza, era necessario definire interfacce separate per ciascuno di essi.
WARNING
Assicurati di includere il file di dichiarazione globale nel tuo tsconfig.json
.
Il valore di ritorno di un matcher deve essere compatibile con la seguente interfaccia:
interface ExpectationResult {
pass: boolean;
message: () => string;
// Se forniti, appariranno automaticamente all'interno di un diff quando
// il matcher fallisce, eliminando la necessità di stampare il diff manualmente.
actual?: unknown;
expected?: unknown;
}
WARNING
Se crei un matcher asincrono, ricorda di await
il risultato (await expect('foo').toBeFoo()
) direttamente nel test:
expect.extend({
async toBeAsyncAssertion() {
// ...
},
});
await expect().toBeAsyncAssertion();
Il primo argomento all'interno della funzione di un matcher è il valore ricevuto (quello all'interno di expect(received)
). Gli argomenti rimanenti vengono passati direttamente al matcher.
La funzione del matcher ha accesso al contesto this
con le seguenti proprietà:
isNot
Restituisce true
se il matcher è stato chiamato con not
(expect(received).not.toBeFoo()
).
promise
Se il matcher è stato chiamato su un valore resolved
o rejected
, questa proprietà conterrà il nome del modificatore. Altrimenti, sarà una stringa vuota.
equals
Questa funzione di utilità consente di confrontare due valori. Restituirà true
se i valori sono uguali, false
altrimenti. Questa funzione è utilizzata internamente da quasi tutti i matcher e supporta nativamente oggetti con matcher asimmetrici.
utils
Contiene un insieme di funzioni di utilità che possono essere utilizzate per visualizzare i messaggi.
Il contesto this
contiene anche informazioni sul test corrente, che possono essere ottenute anche chiamando expect.getState()
. Le proprietà più utili sono:
currentTestName
Nome completo del test corrente (incluso il blocco describe
).
testPath
Percorso del file del test corrente.