Skip to content
Vitest 3
Main Navigation Guia & APIConfiguraçãoModo NavegadorAPI Avançada
3.2.0
2.1.9
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

Introdução

Por que Vitest

Primeiros Passos

Recursos

Configurando o Vitest

API

Referência da API de Teste

Funções Mock

Vi

expect

expectTypeOf

assert

assertType

Guia

Interface de Linha de Comando

Filtragem de Testes

Projetos de Teste

Reporters

Cobertura

Snapshot

Mocking

Paralelismo

Testando Tipos

Vitest UI

Testes no Código-Fonte

Contexto de Testes

Anotações em Testes

Ambiente de Teste

Estendendo Matchers

Integrações com IDEs

Depuração

Erros Comuns

Guia de Migração

Migrando para o Vitest 3.0

Migrando do Jest

Desempenho

Análise de Desempenho de Testes

Melhorando o Desempenho

Modo Navegador

APIs Avançadas

Comparações com Outros Test Runners

Nesta página

Vi ​

O Vitest oferece funções utilitárias para auxiliar no uso do vi. Você pode acessá-lo globalmente (quando a configuração de globais está ativada) ou importá-lo diretamente do vitest:

js
import { vi } from 'vitest';

Módulos Mock ​

Esta seção descreve a API que você pode usar ao simular um módulo. Atenção: o Vitest não suporta a simulação de módulos importados usando require().

vi.mock ​

  • Tipo: (path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void
  • Tipo: <T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void

Substitui todos os módulos importados do path fornecido por outro módulo. Você pode usar aliases do Vite configurados dentro de um caminho. A chamada para vi.mock é elevada (hoisted), portanto, não importa onde você a chama, ela sempre será executada antes de todas as importações. Se precisar referenciar variáveis fora do escopo, defina-as dentro de vi.hoisted e as referencie dentro de vi.mock.

WARNING

vi.mock funciona apenas para módulos que foram importados com a palavra-chave import. Não funciona com require.

Para que vi.mock seja elevado, o Vitest analisa estaticamente seus arquivos. Isso significa que vi que não foi importado diretamente do pacote vitest (por exemplo, de algum arquivo utilitário) não pode ser usado. Use vi.mock com vi importado do vitest, ou ative a opção de configuração globals.

O Vitest não simulará módulos importados em um arquivo de configuração (setup file), pois eles são armazenados em cache quando um arquivo de teste é executado. Você pode chamar vi.resetModules() dentro de vi.hoisted para limpar todos os caches de módulo antes de executar um arquivo de teste.

Se a função factory estiver definida, todas as importações retornarão seu resultado. O Vitest chama a factory apenas uma vez e armazena os resultados em cache para todas as importações subsequentes até que vi.unmock ou vi.doUnmock seja chamado.

Diferente do jest, a factory pode ser assíncrona. Você pode usar vi.importActual ou um auxiliar com a factory passada como primeiro argumento, e obter o módulo original dentro.

Você também pode fornecer um objeto com uma propriedade spy em vez de uma função factory. Se spy for true, o Vitest fará a simulação automática do módulo normalmente, mas não substituirá a implementação das exportações. Isso é útil se você quiser apenas verificar se o método exportado foi chamado corretamente por outro método.

ts
import { calculator } from './src/calculator.ts';

vi.mock('./src/calculator.ts', { spy: true });

// chama a implementação original,
// mas permite afirmar o comportamento mais tarde
const result = calculator(1, 2);

expect(result).toBe(3);
expect(calculator).toHaveBeenCalledWith(1, 2);
expect(calculator).toHaveReturned(3);

O Vitest também suporta uma promessa de módulo em vez de uma string nos métodos vi.mock e vi.doMock para melhor suporte de IDE. Quando o arquivo é movido, o caminho será atualizado, e importOriginal herda o tipo automaticamente. Usar esta assinatura também forçará o tipo de retorno da factory a ser compatível com o módulo original (mantendo as exportações opcionais).

ts
// @filename: ./path/to/module.js
export declare function total(...numbers: number[]): number;
// @filename: test.js
import { vi } from 'vitest';
// ---cut---
vi.mock(import('./path/to/module.js'), async importOriginal => {
  const mod = await importOriginal(); // o tipo é inferido
  //    ^?
  return {
    ...mod,
    // substitui algumas exportações
    total: vi.fn(),
  };
});

Internamente, o Vitest ainda opera em uma string e não em um objeto de módulo.

No entanto, se você estiver usando TypeScript com aliases paths configurados em tsconfig.json, o compilador não conseguirá resolver corretamente os tipos de importação. Para funcionar, substitua todas as importações com alias por seus caminhos relativos correspondentes. Ex: use import('./path/to/module.js') em vez de import('@/module').

WARNING

vi.mock é elevado (em outras palavras, movido) para o topo do arquivo. Isso significa que, sempre que você o escrever (seja dentro de beforeEach ou test), ele será realmente chamado antes disso.

Isso significa que você não pode usar variáveis definidas fora da factory dentro dela.

Se você precisar usar variáveis dentro da factory, tente vi.doMock. Ele funciona da mesma forma, mas não é elevado. Cuidado que ele apenas simula importações subsequentes.

Você também pode referenciar variáveis definidas pelo método vi.hoisted se ele foi declarado antes de vi.mock:

ts
import { namedExport } from './path/to/module.js';

const mocks = vi.hoisted(() => {
  return {
    namedExport: vi.fn(),
  };
});

vi.mock('./path/to/module.js', () => {
  return {
    namedExport: mocks.namedExport,
  };
});

vi.mocked(namedExport).mockReturnValue(100);

expect(namedExport()).toBe(100);
expect(namedExport).toBe(mocks.namedExport);

WARNING

Se você estiver simulando um módulo com exportação padrão, precisará fornecer uma chave default dentro do objeto da função factory retornada. Esta é uma ressalva específica do módulo ES; portanto, a documentação do jest pode diferir, pois o jest usa módulos CommonJS. Por exemplo,

ts
vi.mock('./path/to/module.js', () => {
  return {
    default: { myDefaultKey: vi.fn() },
    namedExport: vi.fn(),
    // etc...
  };
});

Se houver uma pasta __mocks__ ao lado de um arquivo que você está simulando, e a factory não for fornecida, o Vitest tentará encontrar um arquivo com o mesmo nome na subpasta __mocks__ e usá-lo como um módulo real. Se você estiver simulando uma dependência, o Vitest tentará encontrar uma pasta __mocks__ na raiz do projeto (o padrão é process.cwd()). Você pode dizer ao Vitest onde as dependências estão localizadas através da opção de configuração deps.moduleDirectories.

Por exemplo, você tem esta estrutura de arquivo:

- __mocks__
  - axios.js
- src
  __mocks__
    - increment.js
  - increment.js
- tests
  - increment.test.js

Se você chamar vi.mock em um arquivo de teste sem uma factory ou opções fornecidas, ele encontrará um arquivo na pasta __mocks__ para usar como módulo:

ts
import { vi } from 'vitest';

// axios é uma exportação padrão de `__mocks__/axios.js`
import axios from 'axios';

// increment é uma exportação nomeada de `src/__mocks__/increment.js`
import { increment } from '../increment.js';

vi.mock('axios');
vi.mock('../increment.js');

axios.get(`/apples/${increment(1)}`);

WARNING

Atenção: se você não chamar vi.mock, os módulos não são simulados automaticamente. Para replicar o comportamento de simulação automática do Jest, você pode chamar vi.mock para cada módulo necessário dentro de setupFiles.

Se não houver uma pasta __mocks__ ou uma factory fornecida, o Vitest importará o módulo original e fará a simulação automática de todas as suas exportações. Para as regras aplicadas, consulte simulação automática.

vi.doMock ​

  • Tipo: (path: string, factory?: MockOptions | ((importOriginal: () => unknown) => unknown)) => void
  • Tipo: <T>(path: Promise<T>, factory?: MockOptions | ((importOriginal: () => T) => T | Promise<T>)) => void

O mesmo que vi.mock, mas não é elevado para o topo do arquivo, então você pode referenciar variáveis no escopo global do arquivo. A próxima importação dinâmica do módulo será simulada.

WARNING

Isso não simulará módulos que foram importados antes desta chamada. Não se esqueça que todas as importações estáticas em ESM são sempre elevadas, então colocar isso antes da importação estática não forçará que seja chamado antes da importação:

ts
vi.doMock('./increment.js'); // isso será chamado _depois_ da declaração de importação

import { increment } from './increment.js';
ts
export function increment(number) {
  return number + 1;
}
ts
import { beforeEach, test } from 'vitest';
import { increment } from './increment.js';

// o módulo não é simulado, porque vi.doMock ainda não foi chamado
increment(1) === 2;

let mockedIncrement = 100;

beforeEach(() => {
  // você pode acessar variáveis dentro de uma factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }));
});

test('importar o próximo módulo importa o simulado', async () => {
  // a importação original NÃO FOI SIMULADA, porque vi.doMock é avaliado DEPOIS das importações
  expect(increment(1)).toBe(2);
  const { increment: mockedIncrement } = await import('./increment.js');
  // a nova importação dinâmica retorna o módulo simulado
  expect(mockedIncrement(1)).toBe(101);
  expect(mockedIncrement(1)).toBe(102);
  expect(mockedIncrement(1)).toBe(103);
});

vi.mocked ​

  • Tipo: <T>(obj: T, deep?: boolean) => MaybeMockedDeep<T>
  • Tipo: <T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>

Auxiliar de tipo para TypeScript. Apenas retorna o objeto que foi passado.

Quando partial é true, ele esperará um Partial<T> como valor de retorno. Por padrão, isso fará com que o TypeScript acredite que apenas os valores de primeiro nível são simulados. Você pode passar { deep: true } como segundo argumento para dizer ao TypeScript que o objeto inteiro é simulado, se realmente for.

ts
export function add(x: number, y: number): number {
  return x + y;
}

export function fetchSomething(): Promise<Response> {
  return fetch('https://vitest.dev/');
}
ts
import * as example from './example';

vi.mock('./example');

test('1 + 1 é igual a 10', async () => {
  vi.mocked(example.add).mockReturnValue(10);
  expect(example.add(1, 1)).toBe(10);
});

test('valor de retorno simulado com tipagem apenas parcialmente correta', async () => {
  vi.mocked(example.fetchSomething).mockResolvedValue(new Response('hello'));
  vi.mocked(example.fetchSomething, { partial: true }).mockResolvedValue({
    ok: false,
  });
  // vi.mocked(example.someFn).mockResolvedValue({ ok: false }) // isso é um erro de tipo
});

vi.importActual ​

  • Tipo: <T>(path: string) => Promise<T>

Importa o módulo, ignorando todas as verificações se ele deve ser simulado. Pode ser útil se você quiser simular o módulo parcialmente.

ts
vi.mock('./example.js', async () => {
  const originalModule = await vi.importActual('./example.js');

  return { ...originalModule, get: vi.fn() };
});

vi.importMock ​

  • Tipo: <T>(path: string) => Promise<MaybeMockedDeep<T>>

Importa um módulo com todas as suas propriedades (incluindo propriedades aninhadas) simuladas. Segue as mesmas regras que vi.mock. Para as regras aplicadas, consulte simulação automática.

vi.unmock ​

  • Tipo: (path: string | Promise<Module>) => void

Remove o módulo do registro de simulações. Todas as chamadas para importação retornarão o módulo original, mesmo que ele tenha sido simulado antes. Esta chamada é elevada para o topo do arquivo, então ela só irá remover a simulação de módulos que foram definidos em setupFiles, por exemplo.

vi.doUnmock ​

  • Tipo: (path: string | Promise<Module>) => void

O mesmo que vi.unmock, mas não é elevado para o topo do arquivo. A próxima importação do módulo importará o módulo original em vez da simulação. Isso não irá remover a simulação de módulos importados anteriormente.

ts
export function increment(number) {
  return number + 1;
}
ts
import { increment } from './increment.js';

// increment já está simulado, porque vi.mock é elevado
increment(1) === 100;

// isso é elevado, e a factory é chamada antes da importação na linha 1
vi.mock('./increment.js', () => ({ increment: () => 100 }));

// todas as chamadas são simuladas, e `increment` sempre retorna 100
increment(1) === 100;
increment(30) === 100;

// isso não é elevado, então outra importação retornará o módulo não simulado
vi.doUnmock('./increment.js');

// isso AINDA retorna 100, porque `vi.doUnmock` não reavalia um módulo
increment(1) === 100;
increment(30) === 100;

// a próxima importação não é simulada, agora `increment` é a função original que retorna count + 1
const { increment: unmockedIncrement } = await import('./increment.js');

unmockedIncrement(1) === 2;
unmockedIncrement(30) === 31;

vi.resetModules ​

  • Tipo: () => Vitest

Reinicia o registro de módulos limpando o cache de todos os módulos. Isso permite que os módulos sejam reavaliados quando reimportados. Importações de nível superior não podem ser reavaliadas. Pode ser útil para isolar módulos onde o estado local entra em conflito entre os testes.

ts
import { vi } from 'vitest';

import { data } from './data.js'; // Não será reavaliado antes de cada teste

beforeEach(() => {
  vi.resetModules();
});

test('alterar estado', async () => {
  const mod = await import('./some/path.js'); // Será reavaliado
  mod.changeLocalState('new value');
  expect(mod.getLocalState()).toBe('new value');
});

test('módulo tem estado antigo', async () => {
  const mod = await import('./some/path.js'); // Será reavaliado
  expect(mod.getLocalState()).toBe('old value');
});

WARNING

Não redefine o registro de simulações. Para limpar o registro de simulações, use vi.unmock ou vi.doUnmock.

vi.dynamicImportSettled ​

Aguarda o carregamento de todas as importações. Útil, se você tiver uma chamada síncrona que inicia a importação de um módulo que você não pode esperar de outra forma.

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

// não é possível rastrear a importação porque a Promise não é retornada
function renderComponent() {
  import('./component.js').then(({ render }) => {
    render();
  });
}

test('operações são resolvidas', async () => {
  renderComponent();
  await vi.dynamicImportSettled();
  expect(document.querySelector('.component')).not.toBeNull();
});

TIP

Se durante uma importação dinâmica outra importação dinâmica for iniciada, este método aguardará até que todas sejam resolvidas.

Este método também aguardará o próximo tick de setTimeout após a importação ser resolvida, para que todas as operações síncronas sejam concluídas no momento em que for resolvida.

Simulação de Funções e Objetos ​

Esta seção descreve como trabalhar com simulações de método e substituir variáveis de ambiente e globais.

vi.fn ​

  • Tipo: (fn?: Function) => Mock

Cria um spy em uma função, embora possa ser iniciado sem uma. Toda vez que uma função é invocada, ela armazena seus argumentos de chamada, retornos e instâncias. Além disso, você pode manipular seu comportamento com métodos. Se nenhuma função for fornecida, a simulação retornará undefined quando invocada.

ts
const getApples = vi.fn(() => 0);

getApples();

expect(getApples).toHaveBeenCalled();
expect(getApples).toHaveReturnedWith(0);

getApples.mockReturnValueOnce(5);

const res = getApples();
expect(res).toBe(5);
expect(getApples).toHaveNthReturnedWith(2, 5);

vi.mockObject 3.2.0+ ​

  • Tipo: <T>(value: T) => MaybeMockedDeep<T>

Simula profundamente as propriedades e métodos de um determinado objeto da mesma forma que vi.mock() simula as exportações de módulos. Veja simulação automática para detalhes.

ts
const original = {
  simple: () => 'value',
  nested: {
    method: () => 'real',
  },
  prop: 'foo',
};

const mocked = vi.mockObject(original);
expect(mocked.simple()).toBe(undefined);
expect(mocked.nested.method()).toBe(undefined);
expect(mocked.prop).toBe('foo');

mocked.simple.mockReturnValue('mocked');
mocked.nested.method.mockReturnValue('mocked nested');

expect(mocked.simple()).toBe('mocked');
expect(mocked.nested.method()).toBe('mocked nested');

vi.isMockFunction ​

  • Tipo: (fn: Function) => boolean

Verifica se um determinado parâmetro é uma função simulada. Se você estiver usando TypeScript, ele também restringirá seu tipo.

vi.clearAllMocks ​

Chama .mockClear() em todos os spies. Isso limpará o histórico da simulação sem afetar as implementações da simulação.

vi.resetAllMocks ​

Chama .mockReset() em todos os spies. Isso limpará o histórico da simulação e redefinirá a implementação de cada simulação para a original.

vi.restoreAllMocks ​

Chama .mockRestore() em todos os spies. Isso limpará o histórico da simulação, restaurará todas as implementações originais da simulação e restaurará os descritores originais dos objetos espiados.

vi.spyOn ​

  • Tipo: <T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance

Cria um spy em um método ou getter/setter de um objeto semelhante a vi.fn(). Ele retorna uma função simulada.

ts
let apples = 0;
const cart = {
  getApples: () => 42,
};

const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples);
apples = 1;

expect(cart.getApples()).toBe(1);

expect(spy).toHaveBeenCalled();
expect(spy).toHaveReturnedWith(1);

TIP

Em ambientes que suportam Gerenciamento Explícito de Recursos, você pode usar using em vez de const para chamar automaticamente mockRestore em qualquer função simulada quando o bloco contendo for encerrado. Isso é especialmente útil para métodos espiados:

ts
it('chama console.log', () => {
  using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
  debug('mensagem')
  expect(spy).toHaveBeenCalled()
})
// console.log é restaurado aqui

TIP

Você pode chamar vi.restoreAllMocks dentro de afterEach (ou habilitar test.restoreMocks) para restaurar todos os métodos às suas implementações originais. Isso restaurará o descritor de objeto original, então você não poderá alterar a implementação do método:

ts
const cart = {
  getApples: () => 42,
};

const spy = vi.spyOn(cart, 'getApples').mockReturnValue(10);

console.log(cart.getApples()); // 10
vi.restoreAllMocks();
console.log(cart.getApples()); // 42
spy.mockReturnValue(10);
console.log(cart.getApples()); // ainda 42!

TIP

Não é possível espionar métodos exportados no modo navegador. Em vez disso, você pode espionar cada método exportado chamando vi.mock("./file-path.js", { spy: true }). Isso simulará cada exportação, mas manterá sua implementação intacta, permitindo que você afirme se o método foi chamado corretamente.

ts
import { calculator } from './src/calculator.ts';

vi.mock('./src/calculator.ts', { spy: true });

calculator(1, 2);

expect(calculator).toHaveBeenCalledWith(1, 2);
expect(calculator).toHaveReturned(3);

E embora seja possível espionar exportações em jsdom ou outros ambientes Node.js, isso pode mudar no futuro.

vi.stubEnv ​

  • Tipo: <T extends string>(name: T, value: T extends "PROD" | "DEV" | "SSR" ? boolean : string | undefined) => Vitest

Altera o valor da variável de ambiente em process.env e import.meta.env. Você pode restaurar seu valor chamando vi.unstubAllEnvs.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` e `import.meta.env.NODE_ENV`
// são "development" antes de chamar "vi.stubEnv"

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';

vi.stubEnv('NODE_ENV', undefined);

process.env.NODE_ENV === undefined;
import.meta.env.NODE_ENV === undefined;

// não altera outras variáveis de ambiente
import.meta.env.MODE === 'development';

TIP

Você também pode alterar o valor simplesmente atribuindo-o, mas não poderá usar vi.unstubAllEnvs para restaurar o valor anterior:

ts
import.meta.env.MODE = 'test';

vi.unstubAllEnvs ​

  • Tipo: () => Vitest

Restaura todos os valores de import.meta.env e process.env que foram alterados com vi.stubEnv. Quando é chamado pela primeira vez, o Vitest lembra o valor original e o armazenará, até que unstubAllEnvs seja chamado novamente.

ts
import { vi } from 'vitest';

// `process.env.NODE_ENV` e `import.meta.env.NODE_ENV`
// são "development" antes de chamar stubEnv

vi.stubEnv('NODE_ENV', 'production');

process.env.NODE_ENV === 'production';
import.meta.env.NODE_ENV === 'production';

vi.stubEnv('NODE_ENV', 'staging');

process.env.NODE_ENV === 'staging';
import.meta.env.NODE_ENV === 'staging';

vi.unstubAllEnvs();

// restaura para o valor que foi armazenado antes da primeira chamada "stubEnv"
process.env.NODE_ENV === 'development';
import.meta.env.NODE_ENV === 'development';

vi.stubGlobal ​

  • Tipo: (name: string | number | symbol, value: unknown) => Vitest

Altera o valor de uma variável global. Você pode restaurar seu valor original chamando vi.unstubAllGlobals.

ts
import { vi } from 'vitest';

// `innerWidth` é "0" antes de chamar stubGlobal

vi.stubGlobal('innerWidth', 100);

innerWidth === 100;
globalThis.innerWidth === 100;
// se você estiver usando jsdom ou happy-dom
window.innerWidth === 100;

TIP

Você também pode alterar o valor simplesmente atribuindo-o a globalThis ou window (se você estiver usando o ambiente jsdom ou happy-dom), mas não poderá usar vi.unstubAllGlobals para restaurar o valor original:

ts
globalThis.innerWidth = 100;
// se você estiver usando jsdom ou happy-dom
window.innerWidth = 100;

vi.unstubAllGlobals ​

  • Tipo: () => Vitest

Restaura todos os valores globais em globalThis/global (e window/top/self/parent, se você estiver usando o ambiente jsdom ou happy-dom) que foram alterados com vi.stubGlobal. Quando é chamado pela primeira vez, o Vitest lembra o valor original e o armazenará, até que unstubAllGlobals seja chamado novamente.

ts
import { vi } from 'vitest';

const Mock = vi.fn();

// IntersectionObserver é "undefined" antes de chamar "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock);

IntersectionObserver === Mock;
global.IntersectionObserver === Mock;
globalThis.IntersectionObserver === Mock;
// se você estiver usando jsdom ou happy-dom
window.IntersectionObserver === Mock;

vi.unstubAllGlobals();

globalThis.IntersectionObserver === undefined;
'IntersectionObserver' in globalThis === false;
// lança ReferenceError, porque não está definido
IntersectionObserver === undefined;

Timers Falsos ​

Esta seção descreve como trabalhar com timers falsos.

vi.advanceTimersByTime ​

  • Tipo: (ms: number) => Vitest

Este método invocará cada timer iniciado até que o número especificado de milissegundos seja passado ou a fila esteja vazia - o que ocorrer primeiro.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

vi.advanceTimersByTime(150);

// log: 1
// log: 2
// log: 3

vi.advanceTimersByTimeAsync ​

  • Tipo: (ms: number) => Promise<Vitest>

Este método invocará cada timer iniciado até que o número especificado de milissegundos seja passado ou a fila esteja vazia - o que ocorrer primeiro. Isso incluirá timers definidos assincronamente.

ts
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

await vi.advanceTimersByTimeAsync(150);

// log: 1
// log: 2
// log: 3

vi.advanceTimersToNextTimer ​

  • Tipo: () => Vitest

Chamará o próximo timer disponível. Útil para fazer asserções entre cada chamada de timer. Você pode encadear chamadas para gerenciar os timers por conta própria.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

vi.advanceTimersToNextTimer() // log: 1
  .advanceTimersToNextTimer() // log: 2
  .advanceTimersToNextTimer(); // log: 3

vi.advanceTimersToNextTimerAsync ​

  • Tipo: () => Promise<Vitest>

Chamará o próximo timer disponível e aguardará até que seja resolvido, se tiver sido definido assincronamente. Útil para fazer asserções entre cada chamada de timer.

ts
let i = 0;
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50);

await vi.advanceTimersToNextTimerAsync(); // log: 1
expect(console.log).toHaveBeenCalledWith(1);

await vi.advanceTimersToNextTimerAsync(); // log: 2
await vi.advanceTimersToNextTimerAsync(); // log: 3

vi.advanceTimersToNextFrame 2.1.0+ ​

  • Tipo: () => Vitest

Semelhante a vi.advanceTimersByTime, mas avançará os timers pelos milissegundos necessários para executar os callbacks atualmente agendados com requestAnimationFrame.

ts
let frameRendered = false;

requestAnimationFrame(() => {
  frameRendered = true;
});

vi.advanceTimersToNextFrame();

expect(frameRendered).toBe(true);

vi.getTimerCount ​

  • Tipo: () => number

Obtém o número de timers aguardando.

vi.clearAllTimers ​

Remove todos os timers que estão agendados para serem executados. Esses timers nunca serão executados no futuro.

vi.getMockedSystemTime ​

  • Tipo: () => Date | null

Retorna a data atual simulada. Se a data não for simulada, o método retornará null.

vi.getRealSystemTime ​

  • Tipo: () => number

Ao usar vi.useFakeTimers, as chamadas Date.now são simuladas. Se você precisar obter o tempo real em milissegundos, pode chamar esta função.

vi.runAllTicks ​

  • Tipo: () => Vitest

Chama todos os ticks que foram enfileirados por process.nextTick. Isso também executará todas as microtarefas agendadas por elas mesmas.

vi.runAllTimers ​

  • Tipo: () => Vitest

Este método invocará cada timer iniciado até que a fila de timers esteja vazia. Isso significa que cada timer chamado durante runAllTimers será disparado. Se você tiver um intervalo infinito, ele lançará um erro após 10.000 tentativas (pode ser configurado com fakeTimers.loopLimit).

ts
let i = 0;
setTimeout(() => console.log(++i));
const interval = setInterval(() => {
  console.log(++i);
  if (i === 3) {
    clearInterval(interval);
  }
}, 50);

vi.runAllTimers();

// log: 1
// log: 2
// log: 3

vi.runAllTimersAsync ​

  • Tipo: () => Promise<Vitest>

Este método invocará assincronamente cada timer iniciado até que a fila de timers esteja vazia. Isso significa que cada timer chamado durante runAllTimersAsync será disparado, mesmo os timers assíncronos. Se você tiver um intervalo infinito, ele lançará um erro após 10.000 tentativas (pode ser configurado com fakeTimers.loopLimit).

ts
setTimeout(async () => {
  console.log(await Promise.resolve('result'));
}, 100);

await vi.runAllTimersAsync();

// log: result

vi.runOnlyPendingTimers ​

  • Tipo: () => Vitest

Este método chamará cada timer que foi iniciado após a chamada vi.useFakeTimers. Ele não disparará nenhum timer que foi iniciado durante sua chamada.

ts
let i = 0;
setInterval(() => console.log(++i), 50);

vi.runOnlyPendingTimers();

// log: 1

vi.runOnlyPendingTimersAsync ​

  • Tipo: () => Promise<Vitest>

Este método chamará assincronamente cada timer que foi iniciado após a chamada vi.useFakeTimers, mesmo os assíncronos. Ele não disparará nenhum timer que foi iniciado durante sua chamada.

ts
setTimeout(() => {
  console.log(1);
}, 100);
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(2);
    setInterval(() => {
      console.log(3);
    }, 40);
  });
}, 10);

await vi.runOnlyPendingTimersAsync();

// log: 2
// log: 3
// log: 3
// log: 1

vi.setSystemTime ​

  • Tipo: (date: string | number | Date) => void

Se os timers falsos estiverem ativados, este método simula um usuário alterando o relógio do sistema (afetará APIs relacionadas a datas como hrtime, performance.now ou new Date()) - no entanto, ele não disparará nenhum timer. Se os timers falsos não estiverem ativados, este método apenas simulará chamadas Date.*.

Útil se você precisar testar algo que depende da data atual - por exemplo, chamadas Luxon no seu código.

Aceita os mesmos argumentos de string e número que o Date.

ts
const date = new Date(1998, 11, 19);

vi.useFakeTimers();
vi.setSystemTime(date);

expect(Date.now()).toBe(date.valueOf());

vi.useRealTimers();

vi.useFakeTimers ​

  • Tipo: (config?: FakeTimerInstallOpts) => Vitest

Para habilitar a simulação de timers, você precisa chamar este método. Ele envolverá todas as chamadas futuras para timers (como setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate e Date) até que vi.useRealTimers() seja chamado.

A simulação de nextTick não é suportada ao executar o Vitest dentro de node:child_process usando --pool=forks. O NodeJS usa process.nextTick internamente em node:child_process e trava quando é simulado. A simulação de nextTick é suportada ao executar o Vitest com --pool=threads.

A implementação é baseada internamente em @sinonjs/fake-timers.

TIP

vi.useFakeTimers() não simula automaticamente process.nextTick e queueMicrotask. Mas você pode habilitá-lo especificando a opção no argumento toFake: vi.useFakeTimers({ toFake: ['nextTick', 'queueMicrotask'] }).

vi.isFakeTimers ​

  • Tipo: () => boolean

Retorna true se os timers falsos estiverem ativados.

vi.useRealTimers ​

  • Tipo: () => Vitest

Quando os timers se esgotarem, você pode chamar este método para retornar os timers simulados às suas implementações originais. Todos os timers que foram agendados antes serão descartados.

Diversos ​

Um conjunto de funções auxiliares úteis que o Vitest fornece.

vi.waitFor ​

  • Tipo: <T>(callback: WaitForCallback<T>, options?: number | WaitForOptions) => Promise<T>

Aguarda o callback ser executado com sucesso. Se o callback lançar um erro ou retornar uma promessa rejeitada, ele continuará aguardando até que seja bem-sucedido ou atinja o tempo limite.

Se as opções forem definidas como um número, o efeito é equivalente a definir { timeout: options }.

Isso é muito útil quando você precisa esperar que alguma ação assíncrona seja concluída, por exemplo, quando você inicia um servidor e precisa esperar que ele inicie.

ts
import { expect, test, vi } from 'vitest';
import { createServer } from './server.js';

test('Servidor iniciado com sucesso', async () => {
  const server = createServer();

  await vi.waitFor(
    () => {
      if (!server.isReady) {
        throw new Error('Servidor não iniciado');
      }

      console.log('Servidor iniciado');
    },
    {
      timeout: 500, // padrão é 1000
      interval: 20, // padrão é 50
    }
  );
  expect(server.isReady).toBe(true);
});

Também funciona para callbacks assíncronos

ts
// @vitest-environment jsdom

import { expect, test, vi } from 'vitest';
import { getDOMElementAsync, populateDOMAsync } from './dom.js';

test('Elemento existe no DOM', async () => {
  // começa a popular o DOM
  populateDOMAsync();

  const element = await vi.waitFor(
    async () => {
      // tenta obter o elemento até que ele exista
      const element = (await getDOMElementAsync()) as HTMLElement | null;
      expect(element).toBeTruthy();
      expect(element.dataset.initialized).toBeTruthy();
      return element;
    },
    {
      timeout: 500, // padrão é 1000
      interval: 20, // padrão é 50
    }
  );
  expect(element).toBeInstanceOf(HTMLElement);
});

Se vi.useFakeTimers for usado, vi.waitFor chama automaticamente vi.advanceTimersByTime(interval) em cada callback de verificação.

vi.waitUntil ​

  • Tipo: <T>(callback: WaitUntilCallback<T>, options?: number | WaitUntilOptions) => Promise<T>

Isso é semelhante a vi.waitFor, mas se o callback lançar algum erro, a execução é imediatamente interrompida e uma mensagem de erro é recebida. Se o callback retornar um valor falso, a próxima verificação continuará até que um valor verdadeiro seja retornado. Isso é útil quando você precisa esperar que algo exista antes de dar o próximo passo.

Veja o exemplo abaixo. Podemos usar vi.waitUntil para esperar que o elemento apareça na página e, em seguida, podemos fazer algo com o elemento.

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

test('Elemento renderiza corretamente', async () => {
  const element = await vi.waitUntil(() => document.querySelector('.element'), {
    timeout: 500, // padrão é 1000
    interval: 20, // padrão é 50
  });

  // faz algo com o elemento
  expect(element.querySelector('.element-child')).toBeTruthy();
});

vi.hoisted ​

  • Tipo: <T>(factory: () => T) => T

Todas as declarações import estáticas em módulos ES são elevadas para o topo do arquivo, então qualquer código que seja definido antes das importações será realmente executado após as importações serem avaliadas.

No entanto, pode ser útil invocar alguns efeitos colaterais, como simular datas antes de importar um módulo.

Para contornar essa limitação, você pode reescrever importações estáticas em dinâmicas assim:

diff
callFunctionWithSideEffect()
- import { value } from './some/module.js'
+ const { value } = await import('./some/module.js')

Ao executar vitest, você pode fazer isso automaticamente usando o método vi.hoisted. Internamente, o Vitest converterá importações estáticas em dinâmicas com live-bindings preservados.

diff
- callFunctionWithSideEffect()
import { value } from './some/module.js'
+ vi.hoisted(() => callFunctionWithSideEffect())

IMPORTAÇÕES NÃO ESTÃO DISPONÍVEIS

Executar código antes das importações significa que você não pode acessar variáveis importadas porque elas ainda não foram definidas:

ts
import { value } from './some/module.js';

vi.hoisted(() => { value }); // lança um erro

Este código produzirá um erro:

Não é possível acessar '__vi_import_0__' antes da inicialização

Se você precisar acessar uma variável de outro módulo dentro de vi.hoisted, use a importação dinâmica:

ts
await vi.hoisted(async () => {
  const { value } = await import('./some/module.js');
});

No entanto, é desencorajado importar qualquer coisa dentro de vi.hoisted porque as importações já são elevadas - se você precisar executar algo antes que os testes estejam em execução, apenas execute-o no próprio módulo importado.

Este método retorna o valor que foi retornado da factory. Você pode usar esse valor em suas factories vi.mock se precisar de acesso fácil a variáveis definidas localmente:

ts
import { expect, vi } from 'vitest';
import { originalMethod } from './path/to/module.js';

const { mockedMethod } = vi.hoisted(() => {
  return { mockedMethod: vi.fn() };
});

vi.mock('./path/to/module.js', () => {
  return { originalMethod: mockedMethod };
});

mockedMethod.mockReturnValue(100);
expect(originalMethod()).toBe(100);

Observe que este método também pode ser chamado assincronamente, mesmo que seu ambiente não suporte top-level await:

ts
const json = await vi.hoisted(async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  return response.json();
});

vi.setConfig ​

  • Tipo: RuntimeConfig

Atualiza a configuração para o arquivo de teste atual. Este método suporta apenas opções de configuração que afetarão o arquivo de teste atual:

ts
vi.setConfig({
  allowOnly: true,
  testTimeout: 10_000,
  hookTimeout: 10_000,
  clearMocks: true,
  restoreMocks: true,
  fakeTimers: {
    now: new Date(2021, 11, 19),
    // suporta o objeto inteiro
  },
  maxConcurrency: 10,
  sequence: {
    hooks: 'stack',
    // suporta apenas "sequence.hooks"
  },
});

vi.resetConfig ​

  • Tipo: RuntimeConfig

Se vi.setConfig foi chamado antes, isso redefinirá a configuração para o estado original.

Pager
AnteriorFunções Mock
Próximoexpect

Distribuído sob a Licença MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/api/vi

Distribuído sob a Licença MIT.

Copyright (c) 2021-Present Vitest Team