An Async Example
En primer lugar, habilita el soporte de Babel en Jest como se indica en la guía.
Vamos a implementar un sencillo módulo que recupera datos de un API y devuelve el nombre de usuario.
// user.js import request from './request'; export function getUserName(userID) { return request('/users/' + userID).then(user => user.name); }
En la aplicación anterior esperamos que el módulo de request.js
devuelva una promise. Cuando la promise devuelve un valor con then
recibiremos el nombre de usuario.
Ahora imagine una implementación de request.js
que va a la red y obtiene algunos datos de los usuarios:
// request.js const http = require('http'); export default function request(url) { return new Promise(resolve => { // Esto es un ejemplo de http request, para descargar // datos de usuario de una API. // Este modulo esta siendo mockeado en __mocks__/request.js http.get({path: url}, response => { let data = ''; response.on('data', _data => data += _data); response.on('end', () => resolve(data)); }); }); }
Porque no queremos ir a la red en nuestro test, vamos a crear un mock manual para nuestro módulo de request.js
en la carpeta __mocks__
. Podría ser algo como esto:
// __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.substr('/users/'.length), 10); process.nextTick( () => users[userID] ? resolve(users[userID]) : reject({ error: 'User with ' + userID + ' not found.', }) ); }); }
Ahora vamos a escribir un test 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).toEqual('Mark')); });
Llamamos jest.mock('.. /request ')
a Jest a utilizar nuestro mock manual. Se espera it
que el valor devuelto a una promise que va a resolverse. Puedes encadenar tantas promises como quieras y llamar a expect
en cualquier momento, como devolver una promise al final.
.resolves
#
disponible en Jest 20.0.0+ #
There is a less verbose way using resolves
to unwrap the value of a fulfilled promise together with any other matcher. If the promise is rejected, the assertion will fail.
it('works with resolves', () => { expect.assertions(1); return expect(user.getUserName(5)).resolves.toEqual('Paul'); });
async
/await
#
Escribir tests usando la sintaxis async
/await
es sencillo. Así es como usted escribiría el mismo ejemplo anterior:
// async/await can be used. it('works with async/await', async () => { expect.assertions(1); const data = await user.getUserName(4); expect(data).toEqual('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.toEqual('Paul'); });
Para habilitar async/await en tu proyecto, instala babel-preset-env
y activa la función en el archivo .babelrc
.
Manejo de errores #
Los errores pueden ser gestionados usando el método .catch
. Asegúrate de añadir expect.assertions
para verificar que un cierto número de afirmaciones están siendo llamadas. Otherwise a fulfilled promise would not fail the test:
// Testing for async errors using Promise.catch. test('tests error with promises', async () => { expect.assertions(1); return user.getUserName(2).catch(e => expect(e).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 (e) { expect(e).toEqual({ error: 'User with 1 not found.', }); } });
.rejects
#
disponible en Jest 20.0.0+ #
The.rejects
helper works like the .resolves
helper. If the promise is fulfilled, the test will automatically fail.
// 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: ejemplos/async.
Si deseas probar contadores de tiempo, como el setTimeout
, echa un vistazo a la documentación Timer mocks.