expect
Os seguintes tipos são usados nas assinaturas de tipo abaixo:
type Awaitable<T> = T | PromiseLike<T>;expect é usado para criar asserções. Neste contexto, asserções são funções que podem ser chamadas para garantir uma condição. O Vitest fornece asserções chai por padrão e também asserções compatíveis com Jest construídas sobre o chai.
Por exemplo, este código garante que um valor input é igual a 2. Se não for, a asserção lançará um erro e o teste falhará.
import { expect } from 'vitest';
const input = Math.sqrt(4);
expect(input).to.equal(2); // API chai
expect(input).toBe(2); // API jestTecnicamente, esse exemplo não usa a função test, então você verá o erro do Node.js no console em vez da saída do Vitest. Para saber mais sobre test, consulte a Referência da API de Teste.
Além disso, expect pode ser usado estaticamente para acessar os matchers (descritos posteriormente) e muito mais.
WARNING
expect não tem efeito na tipagem dos testes, a menos que a expressão tenha um erro de tipo. Se você quiser usar o Vitest como verificador de tipo, use expectTypeOf ou assertType.
soft
- Tipo:
ExpectStatic & (actual: any) => Assertions
expect.soft funciona de forma semelhante a expect, mas em vez de interromper a execução do teste após uma asserção falhar, ele continua executando e marca o teste como falho. Todos os erros encontrados durante o teste serão exibidos ao final da execução.
import { expect, test } from 'vitest';
test('expect.soft test', () => {
expect.soft(1 + 1).toBe(3); // marca o teste como falha e continua
expect.soft(1 + 2).toBe(4); // marca o teste como falha e continua
});
// Ao final do teste, os erros acima serão exibidos.Ele também pode ser usado em conjunto com expect. Se a asserção expect falhar, o teste será interrompido e todos os erros serão exibidos.
import { expect, test } from 'vitest';
test('expect.soft test', () => {
expect.soft(1 + 1).toBe(3); // marca o teste como falha e continua
expect(1 + 2).toBe(3); // falha e interrompe o teste, todos os erros anteriores serão exibidos
expect.soft(1 + 2).toBe(4); // não executa
});WARNING
expect.soft só pode ser usado dentro da função test.
not
Usar not irá negar a asserção. Por exemplo, este código garante que um valor input não é igual a 2. Se for igual, a asserção lançará um erro e o teste falhará.
import { expect, test } from 'vitest';
const input = Math.sqrt(16);
expect(input).not.to.equal(2); // API chai
expect(input).not.toBe(2); // API jesttoBe
Tipo:
(value: any) => Awaitable<void>toBepode ser usado para verificar se primitivos são iguais ou se objetos compartilham a mesma referência. É o mesmo que chamarexpect(Object.is(3, 3)).toBe(true). Se os objetos não forem os mesmos, mas você quiser verificar se suas estruturas são idênticas, você pode usartoEqual.Por exemplo, o código abaixo verifica se o comerciante tem 13 maçãs.
tsimport { expect, test } from 'vitest'; const stock = { type: 'apples', count: 13, }; test('stock has 13 apples', () => { expect(stock.type).toBe('apples'); expect(stock.count).toBe(13); }); test('stocks are the same', () => { const refStock = stock; // mesma referência expect(stock).toBe(refStock); });Evite usar
toBecom números de ponto flutuante. Como o JavaScript os arredonda,0.1 + 0.2não é estritamente0.3. Para garantir a comparação de números de ponto flutuante de forma confiável, use a asserçãotoBeCloseTo.
toBeCloseTo
Tipo:
(value: number, numDigits?: number) => Awaitable<void>Use
toBeCloseTopara comparar números de ponto flutuante. O argumento opcionalnumDigitslimita o número de dígitos para verificar após o ponto decimal. Por exemplo:tsimport { expect, test } from 'vitest'; test.fails('decimals are not equal in javascript', () => { expect(0.2 + 0.1).toBe(0.3); // 0.2 + 0.1 é 0.30000000000000004 }); test('decimals are rounded to 5 after the point', () => { // 0.2 + 0.1 é 0.30000 | "000000000004" removido expect(0.2 + 0.1).toBeCloseTo(0.3, 5); // nada de 0.30000000000000004 é removido expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50); });
toBeDefined
Tipo:
() => Awaitable<void>toBeDefinedgarante que o valor não é igual aundefined. Um caso de uso útil é verificar se a função retornou algum valor.tsimport { expect, test } from 'vitest'; function getApples() { return 3; } test('function returned something', () => { expect(getApples()).toBeDefined(); });
toBeUndefined
Tipo:
() => Awaitable<void>O oposto de
toBeDefined,toBeUndefinedgarante que o valor é igual aundefined. Um caso de uso útil é verificar se a função não retornou nada.tsimport { expect, test } from 'vitest'; function getApplesFromStock(stock) { if (stock === 'Bill') return 13; } test("mary doesn't have a stock", () => { expect(getApplesFromStock('Mary')).toBeUndefined(); });
toBeTruthy
Tipo:
() => Awaitable<void>toBeTruthygarante que o valor é verdadeiro quando convertido para booleano. Útil se você não se importa com o valor retornado, mas apenas quer saber se ele pode ser convertido paratrue.Por exemplo, com este código, você não se importa com o valor de retorno de
stocks.getInfo- pode ser um objeto complexo, uma string ou qualquer outra coisa. O código ainda funcionará.tsimport { Stocks } from './stocks.js'; const stocks = new Stocks(); stocks.sync('Bill'); if (stocks.getInfo('Bill')) stocks.sell('apples', 'Bill');Então, se você quiser testar se
stocks.getInfoserá truthy, você pode escrever:tsimport { expect, test } from 'vitest'; import { Stocks } from './stocks.js'; const stocks = new Stocks(); test('if we know Bill stock, sell apples to him', () => { stocks.sync('Bill'); expect(stocks.getInfo('Bill')).toBeTruthy(); });Tudo em JavaScript é truthy, exceto
false,0,'',null,undefinedeNaN.
toBeFalsy
Tipo:
() => Awaitable<void>toBeFalsygarante que o valor é falso quando convertido para booleano. Útil se você não se importa com o valor retornado, mas apenas quer saber se ele pode ser convertido parafalse.Por exemplo, com este código, você não se importa com o valor de retorno de
stocks.stockFailed- ele pode retornar qualquer valor falsy, mas o código ainda funcionará.tsimport { Stocks } from './stocks.js'; const stocks = new Stocks(); stocks.sync('Bill'); if (!stocks.stockFailed('Bill')) stocks.sell('apples', 'Bill');Então, se você quiser testar se
stocks.stockFailedserá falsy, você pode escrever:tsimport { expect, test } from 'vitest'; import { Stocks } from './stocks.js'; const stocks = new Stocks(); test("if Bill stock hasn't failed, sell apples to him", () => { stocks.syncStocks('Bill'); expect(stocks.stockFailed('Bill')).toBeFalsy(); });Tudo em JavaScript é truthy, exceto
false,0,'',null,undefinedeNaN.
toBeNull
Tipo:
() => Awaitable<void>toBeNullsimplesmente garante se algo énull. Alias para.toBe(null).tsimport { expect, test } from 'vitest'; function apples() { return null; } test("we don't have apples", () => { expect(apples()).toBeNull(); });
toBeNaN
Tipo:
() => Awaitable<void>toBeNaNsimplesmente garante se algo éNaN. Alias para.toBe(NaN).tsimport { expect, test } from 'vitest'; let i = 0; function getApplesCount() { i++; return i > 1 ? Number.NaN : i; } test('getApplesCount has some unusual side effects...', () => { expect(getApplesCount()).not.toBeNaN(); expect(getApplesCount()).toBeNaN(); });
toBeTypeOf
Tipo:
(c: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => Awaitable<void>toBeTypeOfverifica se um valor é do tipo especificado.tsimport { expect, test } from 'vitest'; const actual = 'stock'; test('stock is type of string', () => { expect(actual).toBeTypeOf('string'); });
toBeInstanceOf
Tipo:
(c: any) => Awaitable<void>toBeInstanceOfverifica se um valor é uma instância da classe especificada.tsimport { expect, test } from 'vitest'; import { Stocks } from './stocks.js'; const stocks = new Stocks(); test('stocks are instance of Stocks', () => { expect(stocks).toBeInstanceOf(Stocks); });
toBeGreaterThan
Tipo:
(n: number | bigint) => Awaitable<void>toBeGreaterThanverifica se o valor é maior que o valor esperado. Valores iguais farão o teste falhar.tsimport { expect, test } from 'vitest'; import { getApples } from './stocks.js'; test('have more then 10 apples', () => { expect(getApples()).toBeGreaterThan(10); });
toBeGreaterThanOrEqual
Tipo:
(n: number | bigint) => Awaitable<void>toBeGreaterThanOrEqualgarante se o valor real é maior ou igual ao valor recebido.tsimport { expect, test } from 'vitest'; import { getApples } from './stocks.js'; test('have 11 apples or more', () => { expect(getApples()).toBeGreaterThanOrEqual(11); });
toBeLessThan
Tipo:
(n: number | bigint) => Awaitable<void>toBeLessThangarante se o valor real é menor que o valor recebido. Valores iguais farão o teste falhar.tsimport { expect, test } from 'vitest'; import { getApples } from './stocks.js'; test('have less then 20 apples', () => { expect(getApples()).toBeLessThan(20); });
toBeLessThanOrEqual
Tipo:
(n: number | bigint) => Awaitable<void>toBeLessThanOrEqualgarante se o valor real é menor ou igual ao valor recebido.tsimport { expect, test } from 'vitest'; import { getApples } from './stocks.js'; test('have 11 apples or less', () => { expect(getApples()).toBeLessThanOrEqual(11); });
toEqual
Tipo:
(received: any) => Awaitable<void>toEqualverifica se o valor é igual ao valor esperado ou se tem a mesma estrutura (comparando-os recursivamente, se forem objetos). Você pode ver a diferença entretoEqualetoBeneste exemplo:tsimport { expect, test } from 'vitest'; const stockBill = { type: 'apples', count: 13, }; const stockMary = { type: 'apples', count: 13, }; test('stocks have the same properties', () => { expect(stockBill).toEqual(stockMary); }); test('stocks are not the same', () => { expect(stockBill).not.toBe(stockMary); });WARNING
Uma comparação profunda não será realizada para objetos
Error. Para testar se algo foi lançado, use a asserçãotoThrowError.
toStrictEqual
Tipo:
(received: any) => Awaitable<void>toStrictEqualverifica se o valor é igual ao valor esperado, tem a mesma estrutura (comparando-os recursivamente, se forem objetos) e é do mesmo tipo.Diferenças de
.toEqual:- As chaves com propriedades
undefinedsão verificadas. ex.{a: undefined, b: 2}não corresponde a{b: 2}ao usar.toStrictEqual. - A dispersão do array é verificada. ex.
[, 1]não corresponde a[undefined, 1]ao usar.toStrictEqual. - Os tipos de objeto são verificados para serem iguais. ex. Uma instância de classe com campos
aebnão será igual a um objeto literal com camposaeb.
tsimport { expect, test } from 'vitest'; class Stock { constructor(type) { this.type = type; } } test('structurally the same, but semantically different', () => { expect(new Stock('apples')).toEqual({ type: 'apples' }); expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' }); });- As chaves com propriedades
toContain
Tipo:
(received: string) => Awaitable<void>toContainverifica se o valor está presente em um array.toContaintambém pode verificar se uma string é uma substring de outra string.tsimport { expect, test } from 'vitest'; import { getAllFruits } from './stocks.js'; test('the fruit list contains orange', () => { expect(getAllFruits()).toContain('orange'); });
toContainEqual
Tipo:
(received: any) => Awaitable<void>toContainEqualverifica se um item com a estrutura e os valores especificados está presente em um array. Funciona comotoEqualpara cada elemento.tsimport { expect, test } from 'vitest'; import { getFruitStock } from './stocks.js'; test('apple available', () => { expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 }); });
toHaveLength
Tipo:
(received: number) => Awaitable<void>toHaveLengthgarante se um objeto tem uma propriedade.lengthe ela está definida como um determinado valor numérico.tsimport { expect, test } from 'vitest'; test('toHaveLength', () => { expect('abc').toHaveLength(3); expect([1, 2, 3]).toHaveLength(3); expect('').not.toHaveLength(3); // não tem .length de 3 expect({ length: 3 }).toHaveLength(3); });
toHaveProperty
Tipo:
(key: any, received?: any) => Awaitable<void>toHavePropertyverifica se um objeto possui uma propriedade com a chavekeyespecificada.Você pode fornecer um argumento de valor opcional, usando igualdade profunda (deep equality), similar ao matcher
toEqual, para comparar o valor da propriedade.tsimport { expect, test } from 'vitest'; const invoice = { isActive: true, 'P.O': '12345', customer: { first_name: 'John', last_name: 'Doe', location: 'China', }, total_amount: 5000, items: [ { type: 'apples', quantity: 10, }, { type: 'oranges', quantity: 5, }, ], }; test('John Doe Invoice', () => { expect(invoice).toHaveProperty('isActive'); // Afirma que a propriedade existe expect(invoice).toHaveProperty('total_amount', 5000); // Afirma que a propriedade existe e o valor é igual expect(invoice).not.toHaveProperty('account'); // Afirma que esta propriedade não existe // Acesso profundo usando notação de ponto expect(invoice).toHaveProperty('customer.first_name'); // Afirma que a propriedade 'customer.first_name' existe expect(invoice).toHaveProperty('customer.last_name', 'Doe'); expect(invoice).not.toHaveProperty('customer.location', 'India'); // Acesso profundo usando um array contendo a chave expect(invoice).toHaveProperty('items[0].type', 'apples'); expect(invoice).toHaveProperty('items.0.type', 'apples'); // A notação de ponto também funciona // Acesso profundo usando um array contendo o caminho da chave expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples'); expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // A notação de string também funciona // Use um array para envolver sua chave para evitar que ela seja interpretada como um caminho de acesso profundo expect(invoice).toHaveProperty(['P.O'], '12345'); });
toMatch
Tipo:
(received: string | regexp) => Awaitable<void>toMatchverifica se uma string corresponde a uma expressão regular ou a outra string.tsimport { expect, test } from 'vitest'; test('top fruits', () => { expect('top fruits include apple, orange and grape').toMatch(/apple/); expect('applefruits').toMatch('fruit'); // toMatch também aceita uma string });
TIP
Se o valor na mensagem de erro estiver truncado, você pode aumentar o valor de chaiConfig.truncateThreshold no seu arquivo de configuração. Consulte chaiConfig.truncateThreshold.
toMatchObject
Tipo:
(received: object | array) => Awaitable<void>toMatchObjectverifica se um objeto corresponde a um subconjunto das propriedades de outro objeto.É útil para verificar se dois arrays têm o mesmo número de elementos e se os elementos correspondem, diferentemente de
arrayContaining, que permite elementos adicionais no array recebido.tsimport { expect, test } from 'vitest'; const johnInvoice = { isActive: true, customer: { first_name: 'John', last_name: 'Doe', location: 'China', }, total_amount: 5000, items: [ { type: 'apples', quantity: 10, }, { type: 'oranges', quantity: 5, }, ], }; const johnDetails = { customer: { first_name: 'John', last_name: 'Doe', location: 'China', }, }; test('invoice has john personal details', () => { expect(johnInvoice).toMatchObject(johnDetails); }); test('the number of elements must match exactly', () => { // Verifica se um array de objetos corresponde expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([ { foo: 'bar' }, { baz: 1 }, ]); });
toThrowError
Tipo:
(received: any) => Awaitable<void>Alias:
toThrowtoThrowErrorverifica se uma função lança um erro quando invocada.Você pode fornecer um argumento opcional para testar se um tipo específico de erro é lançado:
- expressão regular: a mensagem de erro corresponde ao padrão
- string: a mensagem de erro inclui a substring
TIP
Você deve envolver o código em uma função; caso contrário, o erro não será capturado e o teste falhará.
Por exemplo, se quisermos testar se
getFruitStock('pineapples')lança um erro, podemos escrever:tsimport { expect, test } from 'vitest'; function getFruitStock(type) { if (type === 'pineapples') throw new DiabetesError( 'Pineapples are not good for people with diabetes' ); // Faça outras coisas } test('throws on pineapples', () => { // Teste se a mensagem de erro contém "diabetes" em algum lugar: estes são equivalentes expect(() => getFruitStock('pineapples')).toThrowError(/diabetes/); expect(() => getFruitStock('pineapples')).toThrowError('diabetes'); // Teste a mensagem de erro exata expect(() => getFruitStock('pineapples')).toThrowError( /^Pineapples are not good for people with diabetes$/ ); });TIP
Para testar funções assíncronas, use em combinação com rejects.
jsfunction getAsyncFruitStock() { return Promise.reject(new Error('empty')); } test('throws on pineapples', async () => { await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty'); });
toMatchSnapshot
Tipo:
<T>(shape?: Partial<T> | string, message?: string) => voidGarante que um valor corresponda ao snapshot mais recente.
Você pode fornecer um argumento de string
hint(dica) opcional, que será anexado ao nome do teste. Embora o Vitest sempre anexe um número ao final de um nome de snapshot, dicas descritivas curtas podem ser mais úteis do que números para diferenciar vários snapshots em um único blocoitoutest. O Vitest organiza os snapshots por nome no arquivo.snapcorrespondente.TIP
Quando o snapshot não corresponde e causa a falha do teste, se a não correspondência for esperada, você pode pressionar a tecla
upara atualizar o snapshot uma vez. Ou você pode usar as opções de linha de comando-uou--updatepara que o Vitest sempre atualize os snapshots.tsimport { expect, test } from 'vitest'; test('matches snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; expect(data).toMatchSnapshot(); });Você também pode fornecer um formato (shape) de um objeto, se você estiver testando apenas um formato de um objeto e não precisar que ele seja 100% compatível:
tsimport { expect, test } from 'vitest'; test('matches snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; expect(data).toMatchSnapshot({ foo: expect.any(Set) }); });
toMatchInlineSnapshot
Tipo:
<T>(shape?: Partial<T> | string, snapshot?: string, message?: string) => voidGarante que um valor corresponda ao snapshot mais recente.
O Vitest adiciona e atualiza o argumento
inlineSnapshotcomo uma string diretamente no arquivo de teste (em vez de um arquivo.snapexterno).tsimport { expect, test } from 'vitest'; test('matches inline snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; // O Vitest atualizará o seguinte conteúdo ao atualizar o snapshot expect(data).toMatchInlineSnapshot(` { "foo": Set { "bar", "snapshot", }, } `); });Você também pode fornecer um formato (shape) de um objeto, se você estiver testando apenas um formato de um objeto e não precisar que ele seja 100% compatível:
tsimport { expect, test } from 'vitest'; test('matches snapshot', () => { const data = { foo: new Set(['bar', 'snapshot']) }; expect(data).toMatchInlineSnapshot( { foo: expect.any(Set) }, ` { "foo": Any<Set>, } ` ); });
toMatchFileSnapshot
Tipo:
<T>(filepath: string, message?: string) => Promise<void>Versão: Desde Vitest 0.30.0
Compara ou atualiza o snapshot com o conteúdo de um arquivo explicitamente especificado (em vez do arquivo
.snap).tsimport { expect, it } from 'vitest'; it('render basic', async () => { const result = renderHTML(h('div', { class: 'foo' })); await expect(result).toMatchFileSnapshot('./test/basic.output.html'); });Note que, por envolver operações assíncronas de sistema de arquivos, você precisa usar
awaitcomtoMatchFileSnapshot().
toThrowErrorMatchingSnapshot
Tipo:
(message?: string) => voidSimilar a
toMatchSnapshot, mas espera o mesmo valor quetoThrowError.Se a função lançar um
Error, o snapshot será a mensagem de erro. Caso contrário, o snapshot será o valor lançado pela função.
toThrowErrorMatchingInlineSnapshot
Tipo:
(snapshot?: string, message?: string) => voidSimilar a
toMatchInlineSnapshot, mas espera o mesmo valor quetoThrowError.Se a função lançar um
Error, o snapshot será a mensagem de erro. Caso contrário, o snapshot será o valor lançado pela função.
toHaveBeenCalled
Tipo:
() => Awaitable<void>Esta asserção verifica se uma função foi chamada. Requer que uma função espia (spy) seja passada para
expect.tsimport { expect, test, vi } from 'vitest'; const market = { buy(subject: string, amount: number) { // ... }, }; test('spy function', () => { const buySpy = vi.spyOn(market, 'buy'); expect(buySpy).not.toHaveBeenCalled(); market.buy('apples', 10); expect(buySpy).toHaveBeenCalled(); });
toHaveBeenCalledTimes
- Tipo:
(amount: number) => Awaitable<void>
Esta asserção verifica se uma função foi chamada um número específico de vezes. Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function called two times', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenCalledTimes(2);
});toHaveBeenCalledWith
- Tipo:
(...args: any[]) => Awaitable<void>
Esta asserção verifica se uma função foi chamada pelo menos uma vez com os parâmetros especificados. Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenCalledWith('apples', 10);
expect(buySpy).toHaveBeenCalledWith('apples', 20);
});toHaveBeenLastCalledWith
- Tipo:
(...args: any[]) => Awaitable<void>
Esta asserção verifica se uma função foi chamada com os parâmetros especificados em sua última invocação. Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('spy function', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).not.toHaveBeenLastCalledWith('apples', 10);
expect(buySpy).toHaveBeenLastCalledWith('apples', 20);
});toHaveBeenNthCalledWith
- Tipo:
(time: number, ...args: any[]) => Awaitable<void>
Esta asserção verifica se uma função foi chamada com os parâmetros especificados em um momento específico. A contagem começa em 1. Portanto, para verificar a segunda chamada, você usaria .toHaveBeenNthCalledWith(2, ...).
Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
const market = {
buy(subject: string, amount: number) {
// ...
},
};
test('first call of spy function called with right params', () => {
const buySpy = vi.spyOn(market, 'buy');
market.buy('apples', 10);
market.buy('apples', 20);
expect(buySpy).toHaveBeenNthCalledWith(1, 'apples', 10);
});toHaveReturned
- Tipo:
() => Awaitable<void>
Esta asserção verifica se uma função retornou um valor com sucesso pelo menos uma vez (ou seja, não lançou um erro). Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
function getApplesPrice(amount: number) {
const PRICE = 10;
return amount * PRICE;
}
test('spy function returned a value', () => {
const getPriceSpy = vi.fn(getApplesPrice);
const price = getPriceSpy(10);
expect(price).toBe(100);
expect(getPriceSpy).toHaveReturned();
});toHaveReturnedTimes
- Tipo:
(amount: number) => Awaitable<void>
Esta asserção verifica se uma função retornou um valor com sucesso a quantidade exata de vezes (ou seja, não lançou um erro). Requer que uma função espia (spy) seja passada para expect.
import { expect, test, vi } from 'vitest';
test('spy function returns a value two times', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveReturnedTimes(2);
});toHaveReturnedWith
- Tipo:
(returnValue: any) => Awaitable<void>
Você pode usar esta asserção para verificar se uma função retornou um valor específico com sucesso, pelo menos uma vez. Requer que uma função spy seja passada para expect.
import { expect, test, vi } from 'vitest';
test('função spy retorna um produto', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
expect(sell).toHaveReturnedWith({ product: 'apples' });
});toHaveLastReturnedWith
- Tipo:
(returnValue: any) => Awaitable<void>
Você pode usar esta asserção para verificar se uma função retornou um valor específico com sucesso na sua última invocação. Requer que uma função spy seja passada para expect.
import { expect, test, vi } from 'vitest';
test('função spy retorna bananas na última chamada', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveLastReturnedWith({ product: 'bananas' });
});toHaveNthReturnedWith
- Tipo:
(time: number, returnValue: any) => Awaitable<void>
Você pode usar esta asserção para verificar se uma função retornou um valor específico com sucesso em uma chamada específica. Requer que uma função spy seja passada para expect.
import { expect, test, vi } from 'vitest';
test('função spy retorna bananas na segunda chamada', () => {
const sell = vi.fn((product: string) => ({ product }));
sell('apples');
sell('bananas');
expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' });
});toSatisfy
- Tipo:
(predicate: (value: any) => boolean) => Awaitable<void>
Esta asserção verifica se um valor satisfaz uma condição definida por um predicado.
describe('toSatisfy()', () => {
const isOdd = (value: number) => value % 2 !== 0;
it('passa com valor ímpar', () => {
expect(1).toSatisfy(isOdd);
});
it('passa com valor par (negação)', () => {
expect(2).not.toSatisfy(isOdd);
});
});resolves
Tipo:
Promisify<Assertions>resolvessimplifica o teste de código assíncrono. Use-o para extrair o valor de uma promise resolvida e validar seu valor com as asserções usuais. Se a promise for rejeitada, a asserção falhará.Ele retorna o mesmo objeto
Assertions, mas todos os matchers agora retornamPromise, então você precisará usarawaitneles. Também funciona com asserçõeschai.Por exemplo, se você tem uma função que faz uma chamada de API e retorna alguns dados, você pode usar este código para validar o valor de retorno:
tsimport { expect, test } from 'vitest'; async function buyApples() { return fetch('/buy/apples').then(r => r.json()); } test('buyApples retorna o novo ID do estoque', async () => { // toEqual retorna uma promise agora, então você PRECISA usar await await expect(buyApples()).resolves.toEqual({ id: 1 }); // jest API await expect(buyApples()).resolves.to.equal({ id: 1 }); // chai API });WARNING
Se a asserção não for aguardada, você terá um teste falso-positivo que sempre passará. Para garantir que as asserções sejam realmente chamadas, você pode usar
expect.assertions(number).
rejects
Tipo:
Promisify<Assertions>rejectssimplifica o teste de código assíncrono. Use-o para extrair o motivo pelo qual a promise foi rejeitada e validar seu valor com as asserções usuais. Se a promise for resolvida com sucesso, a asserção falhará.Ele retorna o mesmo objeto
Assertions, mas todos os matchers agora retornamPromise, então você precisará usarawaitneles. Também funciona com asserçõeschai.Por exemplo, se você tem uma função que falha quando você a chama, você pode usar este código para validar o motivo da rejeição:
tsimport { expect, test } from 'vitest'; async function buyApples(id) { if (!id) throw new Error('no id'); } test('buyApples lança um erro quando nenhum ID é fornecido', async () => { // toThrow retorna uma promise agora, então você PRECISA usar await await expect(buyApples()).rejects.toThrow('no id'); });WARNING
Se a asserção não for aguardada, você terá um teste falso-positivo que sempre passará. Para garantir que as asserções sejam realmente chamadas, você pode usar
expect.assertions(number).
expect.assertions
Tipo:
(count: number) => voidApós o teste ter passado ou falhado, verifique se um número específico de asserções foi chamado durante um teste. Um caso de uso comum é verificar se um código assíncrono foi executado.
Por exemplo, se temos uma função que chama assincronamente dois matchers, podemos verificar se eles foram realmente chamados.
tsimport { expect, test } from 'vitest'; async function doAsync(...cbs) { await Promise.all(cbs.map((cb, index) => cb({ index }))); } test('todas as asserções são chamadas', async () => { expect.assertions(2); function callback1(data) { expect(data).toBeTruthy(); } function callback2(data) { expect(data).toBeTruthy(); } await doAsync(callback1, callback2); });WARNING
Ao usar
assertionscom testes concorrentes assíncronos, oexpectdo Contexto de Teste local deve ser usado para garantir que o teste correto seja detectado.
expect.hasAssertions
Tipo:
() => voidApós o teste ter passado ou falhado, verifique se pelo menos uma asserção foi chamada durante um teste. Um caso de uso comum é verificar se um código assíncrono foi executado.
Por exemplo, se você tem um código que chama um callback, podemos fazer uma asserção dentro de um callback, mas o teste sempre passará se não verificarmos se uma asserção foi chamada.
tsimport { expect, test } from 'vitest'; import { db } from './db.js'; const cbs = []; function onSelect(cb) { cbs.push(cb); } // after selecting from db, we call all callbacks function select(id) { return db.select({ id }).then(data => { return Promise.all(cbs.map(cb => cb(data))); }); } test('callback foi chamado', async () => { expect.hasAssertions(); onSelect(data => { // should be called on select expect(data).toBeTruthy(); }); // if not awaited, test will fail // if you don't have expect.hasAssertions(), test will pass await select(3); });
expect.unreachable
Tipo:
(message?: string) => neverEste método é usado para afirmar que uma linha de código nunca deve ser alcançada.
Por exemplo, se quisermos testar se
build()lança um erro devido ao recebimento de diretórios sem a pastasrce também lidar com cada erro separadamente, podemos fazer isso:tsimport { expect, test } from 'vitest'; async function build(dir) { if (dir.includes('no-src')) throw new Error(`${dir}/src does not exist`); } const errorDirs = [ 'no-src-folder', // ... ]; test('build falha com "%s"', async dir => { try { await build(dir); expect.unreachable('Não deveria passar no build'); } catch (err: any) { expect(err).toBeInstanceOf(Error); expect(err.stack).toContain('build'); switch (dir) { case 'no-src-folder': expect(err.message).toBe(`${dir}/src does not exist`); break; default: // to exhaust all error tests expect.unreachable('Todos os casos de erro devem ser tratados'); break; } } });
expect.anything
Tipo:
() => anyEste matcher assimétrico, quando usado com verificação de igualdade, sempre retornará
true. Útil se você só quer garantir que a propriedade existe.tsimport { expect, test } from 'vitest'; test('objeto tem a chave "apples"', () => { expect({ apples: 22 }).toEqual({ apples: expect.anything() }); });
expect.any
Tipo:
(constructor: unknown) => anyEste matcher assimétrico, quando usado com uma verificação de igualdade, retornará
truesomente se o valor for uma instância de um construtor especificado. Útil se você tem um valor que é gerado dinamicamente e você só quer saber se ele existe com o tipo correto.tsimport { expect, test } from 'vitest'; import { generateId } from './generators.js'; test('"id" é um número', () => { expect({ id: generateId() }).toEqual({ id: expect.any(Number) }); });
expect.arrayContaining
Tipo:
<T>(expected: T[]) => anyQuando usado com uma verificação de igualdade, este matcher assimétrico retornará
truese o valor for um array e contiver os itens especificados.tsimport { expect, test } from 'vitest'; test('cesta contém maçãs Fuji', () => { const basket = { varieties: ['Empire', 'Fuji', 'Gala'], count: 3, }; expect(basket).toEqual({ count: 3, varieties: expect.arrayContaining(['Fuji']), }); });TIP
Você pode usar
expect.notcom este matcher para negar o valor esperado.
expect.objectContaining
Tipo:
(expected: any) => anyQuando usado com uma verificação de igualdade, este matcher assimétrico retornará
truese o valor tiver uma forma semelhante.tsimport { expect, test } from 'vitest'; test('cesta tem maçãs empire', () => { const basket = { varieties: [ { name: 'Empire', count: 1, }, ], }; expect(basket).toEqual({ varieties: [expect.objectContaining({ name: 'Empire' })], }); });TIP
Você pode usar
expect.notcom este matcher para negar o valor esperado.
expect.stringContaining
Tipo:
(expected: any) => anyQuando usado com uma verificação de igualdade, este matcher assimétrico retornará
truese o valor for uma string e contiver uma substring especificada.tsimport { expect, test } from 'vitest'; test('o nome da variedade contém "Emp"', () => { const variety = { name: 'Empire', count: 1, }; expect(variety).toEqual({ name: expect.stringContaining('Emp'), count: 1, }); });TIP
Você pode usar
expect.notcom este matcher para negar o valor esperado.
expect.stringMatching
Tipo:
(expected: any) => anyQuando usado com uma verificação de igualdade, este matcher assimétrico retornará
truese o valor for uma string e contiver uma substring especificada ou se a string corresponder a uma expressão regular.tsimport { expect, test } from 'vitest'; test('o nome da variedade termina com "re"', () => { const variety = { name: 'Empire', count: 1, }; expect(variety).toEqual({ name: expect.stringMatching(/re$/), count: 1, }); });TIP
Você pode usar
expect.notcom este matcher para negar o valor esperado.
expect.addSnapshotSerializer
Tipo:
(plugin: PrettyFormatPlugin) => voidEste método adiciona serializadores personalizados que são chamados ao criar um snapshot. Este é um recurso avançado - se você quiser saber mais, por favor, leia um guia sobre serializadores personalizados.
Se você estiver adicionando serializadores personalizados, você deve chamar este método dentro de
setupFiles. Isso afetará todos os snapshots.TIP
Se você usou anteriormente o Vue CLI com Jest, você pode querer instalar jest-serializer-vue. Caso contrário, seus snapshots serão envolvidos em uma string, o que faz com que
"seja escapado.
expect.extend
Tipo:
(matchers: MatchersObject) => voidVocê pode estender os matchers padrão com os seus próprios. Esta função é usada para estender o objeto de matchers com matchers personalizados.
Quando você define matchers dessa forma, você também cria matchers assimétricos que podem ser usados como
expect.stringContaining.tsimport { expect, test } from 'vitest'; test('matchers personalizados', () => { expect.extend({ toBeFoo: (received, expected) => { if (received !== 'foo') { return { message: () => `esperado que ${received} seja foo`, pass: false, }; } }, }); expect('foo').toBeFoo(); expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() }); });TIP
Se você quer que seus matchers apareçam em todos os testes, você deve chamar este método dentro de
setupFiles.Esta função é compatível com
expect.extenddo Jest, então qualquer biblioteca que a use para criar matchers personalizados funcionará com o Vitest.Se você estiver usando TypeScript, desde o Vitest 0.31.0 você pode estender a interface
Assertionpadrão em um arquivo de declaração ambient (por exemplo:vitest.d.ts) com o código abaixo:tsinterface CustomMatchers<R = unknown> { toBeFoo(): R; } declare module 'vitest' { interface Assertion<T = any> extends CustomMatchers<T> {} interface AsymmetricMatchersContaining extends CustomMatchers {} }WARNING
Não se esqueça de incluir o arquivo de declaração ambient em seu
tsconfig.json.TIP
Se você quiser saber mais, confira o guia sobre como estender matchers.