Saltar al contenido principal
Versión: 30.0

Un ejemplo asíncrono

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Primero, habilita soporte para Babel en Jest como se documenta en la guía Primeros pasos.

Implementemos un módulo que obtenga datos de usuario desde una API y retorne el nombre de usuario.

user.js
import request from './request';

export function getUserName(userID) {
return request(`/users/${userID}`).then(user => user.name);
}

En la implementación anterior, esperamos que el módulo request.js retorne una promesa. Encadenamos una llamada a then para recibir el nombre de usuario.

Ahora imagina una implementación de request.js que accede a la red y obtiene datos de usuario:

request.js
const http = require('http');

export default function request(url) {
return new Promise(resolve => {
// This is an example of an http request, for example to fetch
// user data from an API.
// This module is being mocked in __mocks__/request.js
http.get({path: url}, response => {
let data = '';
response.on('data', _data => (data += _data));
response.on('end', () => resolve(data));
});
});
}

Como no queremos acceder a la red en nuestras pruebas, crearemos un mock manual para nuestro módulo request.js en la carpeta __mocks__ (la carpeta distingue mayúsculas, __MOCKS__ no funcionará). Podría verse así:

__mocks__/request.js
const users = {
4: {name: 'Mark'},
5: {name: 'Paul'},
};

export default function request(url) {
return new Promise((resolve, reject) => {
const userID = parseInt(url.slice('/users/'.length), 10);
process.nextTick(() =>
users[userID]
? resolve(users[userID])
: reject({
error: `User with ${userID} not found.`,
}),
);
});
}

Ahora escribamos una prueba para nuestra funcionalidad asíncrona.

__tests__/user-test.js
jest.mock('../request');

import * as user from '../user';

// The assertion for a promise must be returned.
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toBe('Mark'));
});

Llamamos a jest.mock('../request') para indicar a Jest que use nuestro mock manual. it espera que el valor de retorno sea una promesa que se resolverá. Puedes encadenar tantas promesas como quieras y llamar a expect en cualquier momento, siempre que retornes una promesa al final.

.resolves

Existe una forma menos verbosa usando resolves para desenvolver el valor de una promesa cumplida junto con cualquier otro comparador. Si la promesa es rechazada, la aserción fallará.

it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toBe('Paul');
});

async/await

También es posible escribir pruebas usando la sintaxis async/await. Así es como escribirías los mismos ejemplos anteriores:

// async/await can be used.
it('works with async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toBe('Mark');
});

// async/await can also be used with `.resolves`.
it('works with async/await and resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toBe('Paul');
});

Para habilitar async/await en tu proyecto, instala @babel/preset-env y activa la característica en tu archivo babel.config.js.

Manejo de errores

Los errores pueden manejarse usando el método .catch. Asegúrate de agregar expect.assertions para verificar que se llama a cierto número de aserciones. De lo contrario, una promesa cumplida no haría fallar la prueba:

// Testing for async errors using Promise.catch.
it('tests error with promises', () => {
expect.assertions(1);
return user.getUserName(2).catch(error =>
expect(error).toEqual({
error: 'User with 2 not found.',
}),
);
});

// Or using async/await.
it('tests error with async/await', async () => {
expect.assertions(1);
try {
await user.getUserName(1);
} catch (error) {
expect(error).toEqual({
error: 'User with 1 not found.',
});
}
});

.rejects

El ayudante .rejects funciona similar a .resolves. Si la promesa se cumple, la prueba fallará automáticamente. expect.assertions(number) no es obligatorio pero se recomienda para verificar que cierto número de aserciones se llamen durante una prueba. De lo contrario es fácil olvidar hacer return/await en las aserciones .resolves.

// Testing for async errors using `.rejects`.
it('tests error with rejects', () => {
expect.assertions(1);
return expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});

// Or using async/await with `.rejects`.
it('tests error with async/await and rejects', async () => {
expect.assertions(1);
await expect(user.getUserName(3)).rejects.toEqual({
error: 'User with 3 not found.',
});
});

El código de este ejemplo está disponible en examples/async.

Si quieres probar temporizadores como setTimeout, revisa la documentación de Mocks para temporizadores.