Skip to content
Vitest 1
Main Navigation GuíaAPIConfiguraciónAvanzado
1.6.1
0.34.6

Español

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

Español

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

Apariencia

Sidebar Navigation

Guía

Por qué Vitest

Empezando

Características

Área de Trabajo

Interfaz de Línea de Comandos

Filtrado de Pruebas

Informes

Cobertura

Capturas instantáneas

Mocking

Pruebas de Tipos

Interfaz de Usuario de Vitest

Modo Navegador

Pruebas en el código fuente

Contexto de prueba

Entorno de Pruebas

Extender Matchers

Integración con IDEs

Depuración

Comparaciones con otros Ejecutores de Pruebas

Guía de Migración

Errores frecuentes

Mejora del rendimiento

API

Referencia de la API de pruebas

Funciones Mock

Vi

expect

expectTypeOf

assert

assertType

Configuración

Administración del archivo de configuración de Vitest

Configuración de Vitest

En esta página

expect ​

Los siguientes tipos se utilizan en las firmas de tipo que se muestran a continuación:

ts
type Awaitable<T> = T | PromiseLike<T>;

expect se utiliza para crear aserciones. En este contexto, las aserciones son funciones que se invocan para verificar una afirmación. Vitest proporciona aserciones de chai de forma predeterminada y también aserciones compatibles con Jest construidas sobre chai.

Por ejemplo, este código afirma que el valor de input es igual a 2. Si no lo es, la aserción lanzará un error y la prueba fallará.

ts
import { expect } from 'vitest';

const input = Math.sqrt(4);

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

Técnicamente, este ejemplo no usa la función test, por lo que en la consola verá un error de Node.js en lugar de la salida de Vitest. Para obtener más información sobre test, consulte Referencia de la API de prueba.

Además, expect se puede usar estáticamente para acceder a las funciones de coincidencia (matchers), que se describen más adelante, y más.

WARNING

expect no tiene efecto en las pruebas de tipos, si la expresión no genera un error de tipo. Si desea utilizar Vitest como verificador de tipos, utilice expectTypeOf o assertType.

soft ​

  • Tipo: ExpectStatic & (actual: any) => Assertions

expect.soft funciona de manera similar a expect, pero en lugar de detener la ejecución de la prueba tras un fallo en la aserción, continúa ejecutándose y marca el fallo como un fallo de prueba. Todos los errores encontrados durante la prueba se mostrarán al finalizar la prueba.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // Marca la prueba como fallida pero continúa
  expect.soft(1 + 2).toBe(4); // Marca la prueba como fallida pero continúa
});
// Al final de la prueba, se mostrarán los errores anteriores.

También se puede utilizar con expect. Si la aserción expect falla, la prueba terminará y se mostrarán todos los errores.

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

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3); // Marca la prueba como fallida pero continúa
  expect(1 + 2).toBe(4); // Falla y termina la prueba, se mostrarán todos los errores anteriores
  expect.soft(1 + 3).toBe(5); // No se llegará a ejecutar
});

WARNING

expect.soft solo se puede utilizar dentro de la función test.

not ​

El uso de not negará la aserción. Por ejemplo, este código afirma que el valor de input no es igual a 2. Si lo es, la aserción lanzará un error y la prueba fallará.

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

const input = Math.sqrt(16);

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

toBe ​

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

toBe se puede utilizar para afirmar si los tipos primitivos son iguales o si los objetos comparten la misma referencia. Es equivalente a expect(Object.is(3, 3)).toBe(true). Si los objetos no son los mismos, pero desea comprobar si sus estructuras son idénticas, puede utilizar toEqual.

Por ejemplo, el siguiente código comprueba si el comerciante tiene 13 manzanas.

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; // misma referencia

  expect(stock).toBe(refStock);
});

Intente no utilizar toBe con números de punto flotante. Dado que JavaScript los redondea, 0.1 + 0.2 no es estrictamente 0.3. Para afirmar de forma fiable los números de punto flotante, utilice la aserción toBeCloseTo.

toBeCloseTo ​

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

Utilice toBeCloseTo para comparar números de punto flotante. El argumento opcional numDigits limita el número de decimales que se deben comprobar. Por ejemplo:

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 es 0.30000000000000004
});

test('decimals are rounded to 5 after the point', () => {
  // 0.2 + 0.1 es 0.30000 | "000000000004" eliminado
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5);
  // no se elimina nada de 0.30000000000000004
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50);
});

toBeDefined ​

  • Tipo: () => Awaitable<void>

toBeDefined afirma que el valor no es igual a undefined. Un caso de uso común es comprobar si una función devolvió un valor.

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

function getApples() {
  return 3;
}

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

toBeUndefined ​

  • Tipo: () => Awaitable<void>

Opuesto a toBeDefined, toBeUndefined afirma que el valor es igual a undefined. Un caso de uso común es comprobar si una función no devolvió ningún valor.

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

toBeTruthy afirma que el valor es verdadero cuando se convierte a booleano. Útil si no importa el valor en sí, sino solo si se evalúa como true en un contexto booleano.

Por ejemplo, si tiene este código, no le importa el valor de retorno de stocks.getInfo: puede ser un objeto complejo, una cadena o cualquier otra cosa. El código seguirá funcionando.

ts
import { Stocks } from './stocks.js';

const stocks = new Stocks();
stocks.sync('Bill');
if (stocks.getInfo('Bill')) stocks.sell('apples', 'Bill');

Por lo tanto, si desea probar que stocks.getInfo será verdadero, podría escribir:

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();
});

En JavaScript, todo se evalúa como verdadero, excepto false, null, undefined, NaN, 0, -0, 0n, "" y document.all.

toBeFalsy ​

  • Tipo: () => Awaitable<void>

toBeFalsy afirma que el valor es falso cuando se convierte a booleano. Útil si no importa el valor en sí, sino solo si se evalúa como false en un contexto booleano.

Por ejemplo, si tiene este código, no le importa el valor de retorno de stocks.stockFailed: puede devolver cualquier valor falso, pero el código seguirá funcionando.

ts
import { Stocks } from './stocks.js';

const stocks = new Stocks();
stocks.sync('Bill');
if (!stocks.stockFailed('Bill')) stocks.sell('apples', 'Bill');

Por lo tanto, si desea probar que stocks.stockFailed será falso, podría escribir:

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();
});

En JavaScript, todo se evalúa como verdadero, excepto false, null, undefined, NaN, 0, -0, 0n, "" y document.all.

toBeNull ​

  • Tipo: () => Awaitable<void>

toBeNull simplemente afirma si algo es 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 simplemente afirma si algo es 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 comprueba si un valor es del 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 comprueba si un valor es una instancia de la clase 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 afirma si el valor real es mayor que el recibido. La prueba fallará si los valores son iguales.

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 afirma si el valor real es mayor o igual que el recibido.

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 afirma si el valor real es menor que el recibido. La prueba fallará si los valores son iguales.

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 afirma si el valor real es menor o igual que el recibido.

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 afirma si el valor real es igual al recibido o tiene la misma estructura, si es un objeto (comparación recursiva). Puede ver la diferencia entre toEqual y toBe en este ejemplo:

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

No se realizará una igualdad profunda para los objetos Error. Solo la propiedad message de un error se considera para la igualdad. Para personalizar la igualdad para verificar propiedades distintas de message, use expect.addEqualityTesters. Para probar si se lanzó algo, use la aserción toThrowError.

toStrictEqual ​

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

toStrictEqual afirma si el valor real es igual al recibido o tiene la misma estructura si es un objeto (comparación recursiva) y del mismo tipo.

Diferencias con .toEqual:

  • Se verifican las propiedades con valor undefined. Por ejemplo, {a: undefined, b: 2} no coincide con { b: 2 } cuando se utiliza .toStrictEqual.
  • Se verifica la dispersión en arrays. Por ejemplo, [, 1] no coincide con [ undefined, 1 ] cuando se utiliza .toStrictEqual.
  • Se verifica que los tipos de objeto coincidan. Por ejemplo, una instancia de clase con los campos a y b no será igual a un objeto literal con los campos a y 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 si el valor real está en una matriz. toContain también puede verificar si una cadena es una subcadena de otra cadena. Desde Vitest 1.0, si está ejecutando pruebas en un entorno similar a un navegador, esta aserción también puede verificar si la clase está contenida en una classList, o si un elemento está dentro de otro.

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

test('la lista de frutas contiene orange', () => {
  expect(getAllFruits()).toContain('orange');

  const element = document.querySelector('#el');
  // element tiene una clase
  expect(element.classList).toContain('flex');
  // element está dentro de otro
  expect(document.querySelector('#wrapper')).toContain(element);
});

toContainEqual ​

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

toContainEqual afirma si un elemento con una estructura y valores específicos está contenido en un arreglo. Realiza una comparación similar a toEqual para cada elemento del array.

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 comprueba si la propiedad .length de un objeto coincide con un valor numérico específico.

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

test('toHaveLength', () => {
  expect('abc').toHaveLength(3);
  expect([1, 2, 3]).toHaveLength(3);

  expect('').not.toHaveLength(3); // no tiene longitud (.length) de 3
  expect({ length: 3 }).toHaveLength(3);
});

toHaveProperty ​

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

toHaveProperty verifica si un objeto tiene una propiedad con la clave key proporcionada.

Opcionalmente, puedes proporcionar un argumento de valor, similar al matcher toEqual, para comparar el valor de la propiedad.

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'); // Verifica que la clave existe
  expect(invoice).toHaveProperty('total_amount', 5000); // Verifica que la clave existe y el valor coincide

  expect(invoice).not.toHaveProperty('account'); // Verifica que la clave no existe.

  // Referencia profunda usando notación de puntos
  expect(invoice).toHaveProperty('customer.first_name');
  expect(invoice).toHaveProperty('customer.last_name', 'Doe');
  expect(invoice).not.toHaveProperty('customer.location', 'India');

  // Referencia profunda usando un array que contiene la clave
  expect(invoice).toHaveProperty('items[0].type', 'apples');
  expect(invoice).toHaveProperty('items.0.type', 'apples'); // La notación de puntos también es válida.

  // Referencia profunda usando un array que contiene el keyPath
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples');
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples'); // La notación de string también es válida.

  // Envuelve tu clave en un array para evitar que la clave se analice como una referencia profunda
  expect(invoice).toHaveProperty(['P.O'], '12345');
});

toMatch ​

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

toMatch verifica si una cadena coincide con una expresión regular o con otra cadena.

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

test('top fruits', () => {
  expect('top fruits include apple, orange and grape').toMatch(/apple/);
  expect('applefruits').toMatch('fruit'); // toMatch también acepta una cadena
});

toMatchObject ​

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

toMatchObject verifica si un objeto coincide con un subconjunto de las propiedades de otro objeto.

También puedes pasar un array de objetos. Esto es útil para comprobar que dos arrays coinciden exactamente en el número de elementos, a diferencia de arrayContaining, que permite elementos adicionales en el array recibido.

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', () => {
  // Comprueba que un array de objetos coincide
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ]);
});

toThrowError ​

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

  • Alias: toThrow

toThrowError verifica si una función lanza un error cuando se ejecuta.

Puedes proporcionar un argumento opcional para verificar que se lanza un error específico:

  • expresión regular: el mensaje de error coincide con el patrón
  • cadena: el mensaje de error incluye la subcadena

TIP

Debes envolver el código en una función; de lo contrario, el error no se capturará y la prueba fallará.

Por ejemplo, si queremos probar que getFruitStock('pineapples') lanza un error, podríamos escribir:

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

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

  // Do some other stuff
}

test('throws on pineapples', () => {
  // Comprueba que el mensaje de error contiene "stock" en alguna parte: estos son equivalentes
  expect(() => getFruitStock('pineapples')).toThrowError(/stock/);
  expect(() => getFruitStock('pineapples')).toThrowError('stock');

  // Prueba el mensaje de error exacto
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not in stock$/
  );
});

TIP

Para probar funciones asíncronas, úsalo en combinación con 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

Asegura que un valor coincida con la última instantánea.

Puedes proporcionar un argumento de cadena hint opcional que se agrega al nombre de la prueba. Aunque Vitest siempre agrega un número al final de un nombre de instantánea, las sugerencias descriptivas breves pueden ser más útiles que los números para diferenciar múltiples instantáneas en un solo bloque it o test. Vitest ordena las instantáneas por nombre en el archivo .snap correspondiente.

TIP

Cuando la instantánea no coincide y causa que la prueba falle, si este desajuste es esperado, puedes presionar la tecla u para actualizar la instantánea manualmente. O puedes pasar las opciones de CLI -u o --update para hacer que Vitest siempre actualice las pruebas.

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

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  expect(data).toMatchSnapshot();
});

También puedes proporcionar una forma de un objeto, si estás probando solo una forma de un objeto, y no necesitas que sea 100% compatible:

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

Asegura que un valor coincida con la última instantánea.

Vitest agrega y actualiza el argumento de cadena inlineSnapshot al matcher en el archivo de prueba (en lugar de un archivo .snap externo).

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

test('matches inline snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) };
  // Vitest will update following content when updating the snapshot
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `);
});

También puedes proporcionar una forma de un objeto, si estás probando solo una forma de un objeto, y no necesitas que sea 100% compatible:

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 o actualiza la instantánea con el contenido de un archivo especificado explícitamente (en lugar del archivo .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');
});

toThrowErrorMatchingSnapshot ​

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

Similar a toMatchSnapshot, pero espera el mismo valor que toThrowError.

toThrowErrorMatchingInlineSnapshot ​

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

Similar a toMatchInlineSnapshot, pero espera el mismo valor que toThrowError.

Si la función lanza un Error, la instantánea será el mensaje de error. De lo contrario, la instantánea será el valor lanzado por la función.

toHaveBeenCalled ​

  • Tipo: () => Awaitable<void>

Esta afirmación es útil para verificar si una función ha sido llamada. Requiere que se pase una función espía a 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 afirmación comprueba si una función fue llamada una cantidad específica de veces. Requiere que se pase una función espía a 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 afirmación comprueba si una función fue llamada al menos una vez con ciertos parámetros. Requiere que se pase una función espía a 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 afirmación comprueba si una función fue llamada con ciertos parámetros en su última invocación. Requiere que se pase una función espía a 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 afirmación comprueba si una función fue llamada con ciertos parámetros en una invocación específica. El conteo comienza en 1. Por lo tanto, para verificar la segunda llamada, usarías .toHaveBeenNthCalledWith(2, ...).

Requiere que se pase una función espía a 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 afirmación comprueba si una función ha devuelto un valor correctamente al menos una vez (es decir, no lanzó un error). Requiere que se pase una función espía a 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 afirmación comprueba si una función ha devuelto un valor correctamente una cantidad exacta de veces (es decir, no lanzó un error). Requiere que se pase una función espía a 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>

Puedes usar esta aserción para verificar si una función espía (spy function) ha retornado un valor específico al menos una vez. Requiere que se pase una función espía a expect.

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

test('la función espía retorna un producto', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');

  expect(sell).toHaveReturnedWith({ product: 'apples' });
});

toHaveLastReturnedWith ​

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

Puedes usar esta aserción para verificar si una función espía (spy function) ha retornado un valor específico en su última invocación. Requiere que se pase una función espía a expect.

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

test('la función espía retorna bananas en la última llamada', () => {
  const sell = vi.fn((product: string) => ({ product }));

  sell('apples');
  sell('bananas');

  expect(sell).toHaveLastReturnedWith({ product: 'bananas' });
});

toHaveNthReturnedWith ​

  • Tipo: (time: number, returnValue: any) => Awaitable<void>

Puedes usar esta aserción para verificar si una función espía (spy function) ha retornado un valor específico en una invocación determinada. Requiere que se pase una función espía a expect.

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

test('la función espía retorna bananas en la segunda llamada', () => {
  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 aserción verifica si un valor cumple con un predicado dado.

ts
import { describe, expect, it } from 'vitest';
describe('toSatisfy()', () => {
  const isOdd = (value: number) => value % 2 !== 0;

  it('pasa con 1', () => {
    expect(1).toSatisfy(isOdd);
  });

  it('pasa con negación', () => {
    expect(2).not.toSatisfy(isOdd);
  });
});

resolves ​

  • Tipo: Promisify<Assertions>

resolves está diseñado para simplificar las aserciones en código asíncrono. Úsalo para extraer el valor resuelto de una promesa y realizar una aserción sobre ese valor utilizando las aserciones habituales. Si la promesa es rechazada, la aserción fallará.

Retorna el mismo objeto Assertions, pero todos los matchers ahora retornan Promise, por lo que necesitarás usar await. También funciona con aserciones de chai.

Por ejemplo, si tienes una función que realiza una llamada a una API y retorna datos, puedes usar este código para realizar una aserción sobre su valor de retorno:

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

async function buyApples() {
  return fetch('/buy/apples').then(r => r.json());
}

test('buyApples retorna el nuevo ID del stock', async () => {
  // toEqual retorna una promesa ahora, así que debes usar await
  await expect(buyApples()).resolves.toEqual({ id: 1 }); // API de Jest
  await expect(buyApples()).resolves.to.equal({ id: 1 }); // API de Chai
});

WARNING

Si no esperas la aserción con await, tendrás una prueba falsamente positiva que siempre pasará. Para asegurarte de que las aserciones se ejecuten realmente, puedes usar expect.assertions(number).

rejects ​

  • Tipo: Promisify<Assertions>

rejects está diseñado para simplificar las aserciones en código asíncrono. Úsalo para extraer la razón por la cual una promesa fue rechazada y realizar una aserción sobre ese valor utilizando las aserciones habituales. Si la promesa se resuelve exitosamente, la aserción fallará.

Retorna el mismo objeto Assertions, pero todos los matchers ahora retornan Promise, por lo que necesitarás usar await. También funciona con aserciones de chai.

Por ejemplo, si tienes una función que falla cuando la llamas, puedes usar este código para realizar una aserción sobre la razón del rechazo:

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

async function buyApples(id) {
  if (!id) throw new Error('no id');
}

test('buyApples lanza un error cuando no se proporciona un ID', async () => {
  // toThrow retorna una promesa ahora, así que debes usar await
  await expect(buyApples()).rejects.toThrow('no id');
});

WARNING

Si no esperas la aserción con await, tendrás una prueba falsamente positiva que siempre pasará. Para asegurarte de que las aserciones se ejecuten realmente, puedes usar expect.assertions(number).

expect.assertions ​

  • Tipo: (count: number) => void

Después de que la prueba haya finalizado (ya sea pasando o fallando), verifica que se haya llamado a un número específico de aserciones durante la prueba. Un caso de uso común es verificar si se ejecutó código asíncrono.

Por ejemplo, si tenemos una función que llama asíncronamente a dos matchers, podemos asegurar que ambos fueron realmente llamados.

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

async function doAsync(...cbs) {
  await Promise.all(cbs.map((cb, index) => cb({ index })));
}

test('todas las aserciones son llamadas', async () => {
  expect.assertions(2);
  function callback1(data) {
    expect(data).toBeTruthy();
  }
  function callback2(data) {
    expect(data).toBeTruthy();
  }

  await doAsync(callback1, callback2);
});

WARNING

Cuando se usa assertions con pruebas concurrentes asíncronas, el expect del Contexto de Prueba local debe ser usado para asegurar que la prueba correcta sea detectada.

expect.hasAssertions ​

  • Tipo: () => void

Después de que la prueba haya finalizado (ya sea pasando o fallando), verifica que se haya llamado al menos a una aserción durante la prueba. Un caso de uso común es verificar si se ejecutó código asíncrono.

Por ejemplo, si tienes un código que llama a un callback, podemos hacer una aserción dentro del callback, pero la prueba siempre pasará si no verificamos si se llamó a alguna aserción.

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

const cbs = [];

function onSelect(cb) {
  cbs.push(cb);
}

// después de seleccionar de la base de datos, llamamos a todos los callbacks
function select(id) {
  return db.select({ id }).then(data => {
    return Promise.all(cbs.map(cb => cb(data)));
  });
}

test('el callback fue llamado', async () => {
  expect.hasAssertions();
  onSelect(data => {
    // debería ser llamado en la selección
    expect(data).toBeTruthy();
  });
  // si no se espera con await, la prueba fallará
  // si no tienes expect.hasAssertions(), la prueba pasará
  await select(3);
});

expect.unreachable ​

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

Este método se usa para asegurar que una línea de código nunca debería ser alcanzada.

Por ejemplo, si queremos probar que build() lanza un error porque los directorios recibidos no tienen una carpeta src, y también manejar cada error por separado, podríamos hacer esto:

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.each(errorDirs)('build falla con "%s"', async dir => {
  try {
    await build(dir);
    expect.unreachable('No debería pasar la compilación'); // No debería completarse la compilación
  } 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:
        // para agotar todas las pruebas de error
        expect.unreachable('Todas las pruebas de error deben ser gestionadas'); // Todas las pruebas de error deben ser gestionadas
        break;
    }
  }
});

expect.anything ​

  • Tipo: () => any

Este matcher asimétrico, cuando se usa en una verificación de igualdad, siempre retornará true. Es útil si solo quieres asegurarte de que una propiedad existe.

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

test('el objeto tiene la clave "apples"', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() });
});

expect.any ​

  • Tipo: (constructor: unknown) => any

Este matcher asimétrico, cuando se usa en una verificación de igualdad, devolverá true solo si el valor es una instancia del constructor especificado. Es útil si tienes un valor que se genera cada vez y solo quieres saber que existe con el tipo apropiado.

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

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

expect.closeTo 1.0.0+ ​

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

expect.closeTo es útil cuando se comparan números de punto flotante en propiedades de objetos o elementos de matriz. Si necesita comparar un número, utilice .toBeCloseTo en su lugar.

El argumento opcional numDigits limita el número de dígitos a verificar después del punto decimal. Para el valor predeterminado 2, el criterio de prueba es Math.abs(expected - received) < 0.005 (es decir, 10 ** -2 / 2).

Por ejemplo, esta prueba pasa con una precisión de 5 dígitos:

js
test('comparar flotante en propiedades de objeto', () => {
  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

Cuando se usa en una verificación de igualdad, este matcher asimétrico retornará true si el valor es un array y contiene los elementos especificados.

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

test('la cesta incluye fuji', () => {
  const basket = {
    varieties: ['Empire', 'Fuji', 'Gala'],
    count: 3,
  };
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji']),
  });
});

TIP

Puedes usar expect.not con este matcher para negar el valor esperado.

expect.objectContaining ​

  • Tipo: (expected: any) => any

Cuando se usa en una verificación de igualdad, este matcher asimétrico retornará true si el valor tiene una estructura similar.

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

test('la cesta tiene manzanas empire', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      },
    ],
  };
  expect(basket).toEqual({
    varieties: [expect.objectContaining({ name: 'Empire' })],
  });
});

TIP

Puedes usar expect.not con este matcher para negar el valor esperado.

expect.stringContaining ​

  • Tipo: (expected: any) => any

Cuando se usa en una verificación de igualdad, este matcher asimétrico retornará true si el valor es un string y contiene una subcadena especificada.

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

test('la variedad tiene "Emp" en su nombre', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  });
});

TIP

Puedes usar expect.not con este matcher para negar el valor esperado.

expect.stringMatching ​

  • Tipo: (expected: any) => any

Cuando se usa en una verificación de igualdad, este matcher asimétrico retornará true si el valor es un string y contiene una subcadena especificada o si el string coincide con una expresión regular.

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

test('la variedad termina con "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  };
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  });
});

TIP

Puedes usar expect.not con este matcher para negar el valor esperado.

expect.addSnapshotSerializer ​

  • Tipo: (plugin: PrettyFormatPlugin) => void

Este método agrega serializadores personalizados que se invocan al crear una instantánea (snapshot). Esta es una característica avanzada; si quieres saber más, consulta la guía sobre serializadores personalizados.

Si estás agregando serializadores personalizados, deberías invocar este método dentro de setupFiles. Esto afectará a cada instantánea.

TIP

Si previamente usaste Vue CLI con Jest, es posible que desees instalar jest-serializer-vue. De lo contrario, tus instantáneas se envolverán en una cadena, lo que provocará que se escape "."

expect.extend ​

  • Tipo: (matchers: MatchersObject) => void

Puedes extender los matchers predeterminados con los tuyos propios. Esta función se usa para extender el objeto de matchers con matchers personalizados.

Cuando defines matchers de esta manera, también creas matchers asimétricos que se pueden usar como expect.stringContaining.

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

test('matchers personalizados', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `se esperaba que ${received} fuera foo`,
          pass: false,
        };
      }
    },
  });

  expect('foo').toBeFoo();
  expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() });
});

TIP

Si quieres que tus matchers aparezcan en cada prueba, deberías invocar este método dentro de setupFiles.

Esta función es compatible con expect.extend de Jest, por lo que cualquier librería que lo use para crear matchers personalizados funcionará con Vitest.

Si estás usando TypeScript, a partir de Vitest 0.31.0 puedes extender la interfaz Assertion predeterminada en un archivo de declaración de entorno (p. ej., vitest.d.ts) con el siguiente código:

ts
interface CustomMatchers<R = unknown> {
  toBeFoo: () => R;
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}

WARNING

No olvides incluir el archivo de declaración en tu tsconfig.json.

TIP

Si quieres saber más, revisa la guía sobre cómo extender matchers.

expect.addEqualityTesters 1.2.0+ ​

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

Puede utilizar este método para definir evaluadores personalizados, que son métodos utilizados por los comparadores, para probar si dos objetos son iguales. Es compatible con expect.addEqualityTesters de 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('evaluador de igualdad personalizado', () => {
  expect(new AnagramComparator('listen')).toEqual(
    new AnagramComparator('silent')
  );
});
Pager
AnteriorVi
SiguienteexpectTypeOf

Publicado bajo la licencia MIT.

Copyright (c) 2024 Mithril Contributors

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

Publicado bajo la licencia MIT.

Copyright (c) 2024 Mithril Contributors