Un exemple asynchrone
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
Commencez par activer la prise en charge de Babel dans Jest comme indiqué dans le guide Premiers pas.
Implémentons un module qui récupère les données utilisateur depuis une API et retourne le nom d'utilisateur.
import request from './request';
export function getUserName(userID) {
return request(`/users/${userID}`).then(user => user.name);
}
Dans l'implémentation ci-dessus, nous attendons que le module request.js retourne une promesse. Nous enchaînons un appel à then pour récupérer le nom d'utilisateur.
Imaginez maintenant une implémentation de request.js qui accède au réseau pour récupérer des données utilisateur :
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));
});
});
}
Comme nous ne voulons pas accéder au réseau dans nos tests, nous allons créer un mock manuel pour notre module request.js dans le dossier __mocks__ (le nom du dossier est sensible à la casse, __MOCKS__ ne fonctionnera pas). Il pourrait ressembler à ceci :
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.`,
}),
);
});
}
Écrivons maintenant un test pour notre fonctionnalité asynchrone.
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'));
});
Nous appelons jest.mock('../request') pour indiquer à Jest d'utiliser notre mock manuel. it attend que la valeur retournée soit une promesse qui sera résolue. Vous pouvez enchaîner autant de promesses que vous le souhaitez et appeler expect à tout moment, tant que vous retournez une promesse à la fin.
.resolves
Il existe une méthode moins verbeuse utilisant resolves pour extraire la valeur d'une promesse tenue avec n'importe quel autre matcher. Si la promesse est rejetée, l'assertion échouera.
it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toBe('Paul');
});
async/await
Il est également possible d'écrire des tests en utilisant la syntaxe async/await. Voici comment vous pourriez écrire les mêmes exemples :
// 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');
});
Pour activer async/await dans votre projet, installez @babel/preset-env et activez la fonctionnalité dans votre fichier babel.config.js.
Gestion des erreurs
Les erreurs peuvent être gérées avec la méthode .catch. Assurez-vous d'ajouter expect.assertions pour vérifier qu'un certain nombre d'assertions sont appelées. Sinon, une promesse tenue ne ferait pas échouer le test :
// 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
L'assistant .rejects fonctionne comme .resolves. Si la promesse est tenue, le test échouera automatiquement. expect.assertions(number) n'est pas obligatoire mais recommandé pour vérifier qu'un certain nombre d'assertions sont appelées pendant un test. Il est sinon facile d'oublier de return/await les assertions .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.',
});
});
Le code de cet exemple est disponible sur examples/async.
Si vous souhaitez tester des minuteries comme setTimeout, consultez la documentation Timer mocks.