Skip to content
Vitest 1
Main Navigation GuiaAPIConfiguraçãoAvançado
1.6.1
0.34.6

Português – Brasil

English
简体中文
繁體中文
Español
Français
Русский
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Português – Brasil

English
简体中文
繁體中文
Español
Français
Русский
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Aparência

Sidebar Navigation

Guia

Por que Vitest

Primeiros Passos

Recursos

Workspace

Interface de Linha de Comando

Filtrando Testes

Reporters

Cobertura

Snapshot

Mocking

Testando Tipos

Vitest UI

Modo Navegador

Testes no Código Fonte

Contexto de Teste

Ambiente de Teste

Expandindo Matchers

Integrações de IDE

Depuração

Comparações com Outros Executores de Teste

Guia de Migração

Erros Comuns

Otimizando o Desempenho

API

Referência da API de Teste

Funções Mock

Vi

expect

expectTypeOf

assert

assertType

Configuração

Gerenciando o Arquivo de Configuração do Vitest

Configurando o Vitest

Nesta página

expect ​

Os seguintes tipos são usados nas assinaturas de tipo abaixo:

ts
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á.

ts
import { expect } from 'vitest';

const input = Math.sqrt(4);

expect(input).to.equal(2); // API chai
expect(input).toBe(2); // API jest

Tecnicamente, 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.

ts
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.

ts
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(4); // falha e interrompe o teste, todos os erros anteriores serão exibidos
  expect.soft(1 + 3).toBe(5); // 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á.

ts
import { expect, test } from 'vitest';

const input = Math.sqrt(16);

expect(input).not.to.equal(2); // API chai
expect(input).not.toBe(2); // API jest

toBe ​

  • Tipo: (value: any) => Awaitable<void>

toBe pode ser usado para verificar se primitivos são iguais ou se objetos compartilham a mesma referência. É o mesmo que chamar expect(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 usar toEqual.

Por exemplo, o código abaixo verifica se o comerciante tem 13 maçãs.

ts
import { 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 toBe com números de ponto flutuante. Como o JavaScript os arredonda, 0.1 + 0.2 não é estritamente 0.3. Para garantir a comparação de números de ponto flutuante de forma confiável, use a asserção toBeCloseTo.

toBeCloseTo ​

  • Tipo: (value: number, numDigits?: number) => Awaitable<void>

Use toBeCloseTo para comparar números de ponto flutuante. O argumento opcional numDigits limita o número de dígitos para verificar após o ponto decimal. Por exemplo:

ts
import { 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>

toBeDefined garante que o valor não é igual a undefined. Um caso de uso útil é verificar se a função retornou algum valor.

ts
import { expect, test } from 'vitest';

function getApples() {
  return 3;
}

test('function returned something', () => {
  expect(getApples()).toBeDefined();
});

toBeUndefined ​

  • Tipo: () => Awaitable<void>

O oposto de toBeDefined, toBeUndefined garante que o valor é igual a undefined. Um caso de uso útil é verificar se a função não retornou nada.

ts
import { expect, test } from 'vitest';

function getApplesFromStock(stock: string) {
  if (stock === 'Bill') return 13;
}

test("mary doesn't have a stock", () => {
  expect(getApplesFromStock('Mary')).toBeUndefined();
});

toBeTruthy ​

  • Tipo: () => Awaitable<void>

toBeTruthy garante 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 para true.

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á.

ts
import { 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.getInfo será truthy, você pode escrever:

ts
import { 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, null, undefined, NaN, 0, -0, 0n, "" e document.all.

toBeFalsy ​

  • Tipo: () => Awaitable<void>

toBeFalsy garante 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 para false.

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á.

ts
import { 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.stockFailed será falsy, você pode escrever:

ts
import { 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, null, undefined, NaN, 0, -0, 0n, "" e document.all.

toBeNull ​

  • Tipo: () => Awaitable<void>

toBeNull simplesmente garante se algo é null. Alias para .toBe(null).

ts
import { expect, test } from 'vitest';

function apples() {
  return null;
}

test("we don't have apples", () => {
  expect(apples()).toBeNull();
});

toBeNaN ​

  • Tipo: () => Awaitable<void>

toBeNaN simplesmente garante se algo é NaN. Alias para .toBe(NaN).

ts
import { 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>

toBeTypeOf verifica se um valor é do tipo especificado.

ts
import { expect, test } from 'vitest';

const actual = 'stock';

test('stock is type of string', () => {
  expect(actual).toBeTypeOf('string');
});

toBeInstanceOf ​

  • Tipo: (c: any) => Awaitable<void>

toBeInstanceOf verifica se um valor é uma instância da classe especificada.

ts
import { 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>

toBeGreaterThan verifica se o valor é maior que o valor esperado. Valores iguais farão o teste falhar.

ts
import { 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>

toBeGreaterThanOrEqual garante se o valor real é maior ou igual ao valor recebido.

ts
import { 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>

toBeLessThan garante se o valor real é menor que o valor recebido. Valores iguais farão o teste falhar.

ts
import { 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>

toBeLessThanOrEqual garante se o valor real é menor ou igual ao valor recebido.

ts
import { 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>

toEqual verifica 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 entre toEqual e toBe neste exemplo:

ts
import { 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 igualdade profunda não será realizada para objetos Error. Apenas a propriedade message de um Error é considerada para igualdade. Para customizar a igualdade e verificar propriedades além de message, use expect.addEqualityTesters. Para testar se algo foi lançado, use a asserção toThrowError.

toStrictEqual ​

  • Tipo: (received: any) => Awaitable<void>

toStrictEqual verifica 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 undefined sã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 a e b não será igual a um objeto literal com campos a e b.
ts
import { 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' });
});

toContain ​

  • Tipo: (received: string) => Awaitable<void>

toContain afirma se o valor atual está em um array. toContain também pode verificar se uma string é uma substring de outra string. Desde o Vitest 1.0, se você estiver executando testes em um ambiente semelhante ao navegador, esta asserção também pode verificar se a classe está contida em um classList ou se um elemento está dentro de outro.

ts
import { expect, test } from 'vitest';
import { getAllFruits } from './stocks.js';

test('the fruit list contains orange', () => {
  expect(getAllFruits()).toContain('orange');

  const element = document.querySelector('#el');
  // element has a class
  expect(element.classList).toContain('flex');
  // element is inside another one
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

  • Tipo: (received: any) => Awaitable<void>

toContainEqual verifica se um item com a estrutura e os valores especificados está presente em um array. Funciona como toEqual para cada elemento.

ts
import { 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>

toHaveLength garante se um objeto tem uma propriedade .length e ela está definida como um determinado valor numérico.

ts
import { 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>

toHaveProperty verifica se um objeto possui uma propriedade com a chave key especificada.

Você pode fornecer um argumento de valor opcional, usando igualdade profunda (deep equality), similar ao matcher toEqual, para comparar o valor da propriedade.

ts
import { 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>

toMatch verifica se uma string corresponde a uma expressão regular ou a outra string.

ts
import { 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
});

toMatchObject ​

  • Tipo: (received: object | array) => Awaitable<void>

toMatchObject verifica 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.

ts
import { 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: toThrow

toThrowError verifica 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:

ts
import { expect, test } from 'vitest';

function getFruitStock(type: string) {
  if (type === 'pineapples') throw new Error('Pineapples are not in stock');

  // Faça outras coisas
}

test('throws on pineapples', () => {
  // Teste se a mensagem de erro contém "stock" em algum lugar: estes são equivalentes
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Teste a mensagem de erro exata
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not in stock$/
  );
});

TIP

Para testar funções assíncronas, use em combinação com rejects.

js
function 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) => void

Garante 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 bloco it ou test. O Vitest organiza os snapshots por nome no arquivo .snap correspondente.

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 u para atualizar o snapshot uma vez. Ou você pode usar as opções de linha de comando -u ou --update para que o Vitest sempre atualize os snapshots.

ts
import { 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:

ts
import { 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) => void

Garante que um valor corresponda ao snapshot mais recente.

O Vitest adiciona e atualiza o argumento inlineSnapshot como uma string diretamente no arquivo de teste (em vez de um arquivo .snap externo).

ts
import { 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:

ts
import { 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 0.30.0+ ​

  • Tipo: <T>(filepath: string, message?: string) => Promise<void>

Compara ou atualiza o snapshot com o conteúdo de um arquivo explicitamente especificado (em vez do arquivo .snap).

ts
import { 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 await com toMatchFileSnapshot().

toThrowErrorMatchingSnapshot ​

  • Tipo: (message?: string) => void

Similar a toMatchSnapshot, mas espera o mesmo valor que toThrowError.

toThrowErrorMatchingInlineSnapshot ​

  • Tipo: (snapshot?: string, message?: string) => void

Similar a toMatchInlineSnapshot, mas espera o mesmo valor que toThrowError.

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.

ts
import { 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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
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.

ts
import { describe, expect, it } from 'vitest';
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>

resolves simplifica 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 retornam Promise, então você precisará usar await neles. Também funciona com asserções chai.

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:

ts
import { 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>

rejects simplifica 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 retornam Promise, então você precisará usar await neles. Também funciona com asserções chai.

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:

ts
import { 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) => void

Apó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.

ts
import { 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 assertions com testes concorrentes assíncronos, o expect do Contexto de Teste local deve ser usado para garantir que o teste correto seja detectado.

expect.hasAssertions ​

  • Tipo: () => void

Apó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.

ts
import { 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) => never

Este 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 pasta src e também lidar com cada erro separadamente, podemos fazer isso:

ts
import { 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: () => any

Este matcher assimétrico, quando usado com verificação de igualdade, sempre retornará true. Útil se você só quer garantir que a propriedade existe.

ts
import { expect, test } from 'vitest';

test('objeto tem a chave "apples"', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});

expect.any ​

  • Tipo: (constructor: unknown) => any

Este matcher assimétrico, quando usado com uma verificação de igualdade, retornará true somente 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.

ts
import { expect, test } from 'vitest';
import { generateId } from './generators.js';

test('"id" é um número', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) });
});

expect.closeTo 1.0.0+ ​

  • Tipo: (expected: any, precision?: number) => any

expect.closeTo é útil quando se compara números de ponto flutuante em propriedades de objetos ou itens de array. Se você precisar comparar um número, use .toBeCloseTo em vez disso.

O argumento opcional numDigits limita o número de dígitos para verificar depois do ponto decimal. Para o valor padrão 2, o critério de teste é Math.abs(expected - received) < 0.005 (isto é, 10 ** -2 / 2).

Por exemplo, este teste passa com uma precisão de 5 dígitos:

js
test('compare float in object properties', () => {
  expect({
    title: '0.1 + 0.2',
    sum: 0.1 + 0.2,
  }).toEqual({
    title: '0.1 + 0.2',
    sum: expect.closeTo(0.3, 5),
  });
});

expect.arrayContaining ​

  • Tipo: <T>(expected: T[]) => any

Quando usado com uma verificação de igualdade, este matcher assimétrico retornará true se o valor for um array e contiver os itens especificados.

ts
import { 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.not com este matcher para negar o valor esperado.

expect.objectContaining ​

  • Tipo: (expected: any) => any

Quando usado com uma verificação de igualdade, este matcher assimétrico retornará true se o valor tiver uma forma semelhante.

ts
import { 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.not com este matcher para negar o valor esperado.

expect.stringContaining ​

  • Tipo: (expected: any) => any

Quando usado com uma verificação de igualdade, este matcher assimétrico retornará true se o valor for uma string e contiver uma substring especificada.

ts
import { 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.not com este matcher para negar o valor esperado.

expect.stringMatching ​

  • Tipo: (expected: any) => any

Quando usado com uma verificação de igualdade, este matcher assimétrico retornará true se o valor for uma string e contiver uma substring especificada ou se a string corresponder a uma expressão regular.

ts
import { 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.not com este matcher para negar o valor esperado.

expect.addSnapshotSerializer ​

  • Tipo: (plugin: PrettyFormatPlugin) => void

Este 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) => void

Você 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.

ts
import { 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.extend do 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 Assertion padrão em um arquivo de declaração ambient (por exemplo: vitest.d.ts) com o código abaixo:

ts
interface 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.

expect.addEqualityTesters 1.2.0+ ​

  • Tipo: (tester: Array<Tester>) => void

Você pode usar este método para definir testers customizados, que são métodos usados por matchers para testar se dois objetos são iguais. É compatível com o expect.addEqualityTesters do Jest.

ts
import { expect, test } from 'vitest';

class AnagramComparator {
  public word: string;

  constructor(word: string) {
    this.word = word;
  }

  equals(other: AnagramComparator): boolean {
    const cleanStr1 = this.word.replace(/ /g, '').toLowerCase();
    const cleanStr2 = other.word.replace(/ /g, '').toLowerCase();

    const sortedStr1 = cleanStr1.split('').sort().join('');
    const sortedStr2 = cleanStr2.split('').sort().join('');

    return sortedStr1 === sortedStr2;
  }
}

function isAnagramComparator(a: unknown): a is AnagramComparator {
  return a instanceof AnagramComparator;
}

function areAnagramsEqual(a: unknown, b: unknown): boolean | undefined {
  const isAAnagramComparator = isAnagramComparator(a);
  const isBAnagramComparator = isBAnagramComparator(b);

  if (isAAnagramComparator && isBAnagramComparator) return a.equals(b);
  else if (isAAnagramComparator === isBAnagramComparator) return undefined;
  else return false;
}

expect.addEqualityTesters([areAnagramsEqual]);

test('custom equality tester', () => {
  expect(new AnagramComparator('listen')).toEqual(
    new AnagramComparator('silent')
  );
});
Pager
AnteriorVi
PróximoexpectTypeOf

Distribuído sob a Licença MIT.

Copyright (c) 2024 Mithril Contributors

https://v1.vitest.dev/api/expect

Distribuído sob a Licença MIT.

Copyright (c) 2024 Mithril Contributors