An Async Example
Primeiro, ative o suporte para Babel em Jest conforme documentado no guia de Introdução.
Vamos implementar um módulo simples que busca dados de usuário de uma API e retorna o nome de usuário.
// user.js import request from './request'; export function getUserName(userID) { return request('/users/' + userID).then(user => user.name); }
Na implementação acima esperamos que o módulo request.js
retorne uma promessa. Nós encadeamos uma chamada para then
receber o nome de usuário.
Agora imagine uma implementação de request.js
que vai para a rede e busca alguns dados do usuário:
// request.js const http = require('http'); export default function request(url) { return new Promise(resolve => { // Isto é um exemplo de uma requisição http, por exemplo para buscar // dados de usuário de uma API. // Este módulo está sendo simulado em __mocks__/request.js http.get({path: url}, response => { let data = ''; response.on('data', _data => data += _data); response.on('end', () => resolve(data)); }); }); }
Porque não queremos acessar a rede em nosso teste, nós vamos criar uma simulação (mock, em inglês) manual para nosso módulo request.js
na pasta __mocks__
. Pode ficar parecido com:
// __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.', }) ); }); }
Agora vamos escrever um teste para a nossa funcionalidade async.
// __tests__/user-test.js jest.mock('../request'); import * as user from '../user'; // A afirmação para uma promessa deve ser retornada. it('funciona com promessas', () => { expect.assertions(1); return user.getUserName(4).then(data => expect(data).toEqual('Mark')); });
Nós chamamos jest.mock('../request')
para informar Jest para usar nossa simulação manual. it
espera que o valor de retorno seja uma promessa que vai ser resolvida. Você pode encadear tantas Promessas quanto você quiser e chamar expect
a qualquer momento, contanto que você retorne uma Promessa no final.
.resolves
#
disponível no Jest 20.0.0+ #
Existe uma maneira menos verbosa usando resolves
para decodificar o valor de uma promessa cumprida, juntamente com quaisquer outro matcher. Se a promessa for rejeitada, a afirmação falhará.
it('funciona com resolves', () => { expect.assertions(1); return expect(user.getUserName(5)).resolves.toEqual('Paul'); });
async
/await
#
Escrever testes usando async
/await
é fácil. Aqui está como você poderia escrever os mesmos exemplos de antes:
// async/await pode ser usado. it('funciona com async/await', async () => { expect.assertions(1); const data = await user.getUserName(4); expect(data).toEqual('Mark'); }); // async/await também pode ser usado com `.resolves`. it('funciona com async/await e resolves', async () => { expect.assertions(1); await expect(user.getUserName(5)).resolves.toEqual('Paul'); });
Para habilitar async/await em seu projeto, instale babel-preset-env
e habilite o recurso no arquivo .babelrc
.
Tratamento de erros #
Erros podem ser tratados usando o método .catch
. Se certifique de adicionar expect.assertions
para verificar que um certo número de afirmações são chamadas. Caso contrário, uma promessa cumprida não falharia no teste:
// Testando para erros async usando Promise.catch. test('testa erro para promessas', async () => { expect.assertions(1); return user.getUserName(2).catch(e => expect(e).toEqual({ error: 'User with 2 not found.', }) ); }); // Ou usando async/await. it('testa erro com async/await', async () => { expect.assertions(1); try { await user.getUserName(1); } catch (e) { expect(e).toEqual({ error: 'User with 1 not found.', }); } });
.rejects
#
disponível no Jest 20.0.0+ #
O auxiliar .rejects
funciona como o auxiliar .resolves
. Se a promessa é cumprida, o teste automaticamente irá falhar.
// Testando para erros async usando `.rejects`. it('testa erro com rejects', () => { expect.assertions(1); return expect(user.getUserName(3)).rejects.toEqual({ error: 'User with 3 not found.', }); }); // Ou usando async/await com `.rejects`. it('testa erro com async/await e rejects', async () => { expect.assertions(1); await expect(user.getUserName(3)).rejects.toEqual({ error: 'User with 3 not found.', }); });
O código para esse exemplo está disponível em examples/async.
Se você gostaria de testar temporizadores, como setTimeout
, dê uma olhada na documentação Simulações de Temporizador.