Un exemple Async
Tout d’abord, activez le support de Babel dans Jest comme indiqué dans le guide Mise en route.
Implémentons un module qui récupère les données utilisateur d'une API et retourne le nom de l'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 du module request.js
qu'il renvoie une promesse. Nous enchaînons un appel à then
pour recevoir le nom de l'utilisateur.
Imaginez maintenant une implémentation de request.js
qui se connecte au réseau et récupère certaines données utilisateur :
const http = require('http');
export default function request(url) {
return new Promise(resolve => {
// Ceci est un exemple de requête http, par exemple pour récupérer
// des données utilisateur à partir d'une API.
// Ce module est simulé dans __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 aller sur le réseau dans notre test, nous allons créer un simulateur manuel pour notre module request.js
dans le dossier __mocks__
(le 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: `Utilisateur avec ${userID} non trouvé.`,
}),
);
});
}
Maintenant, écrivons un test pour notre fonctionnalité asynchrone.
jest.mock('../request');
import * as user from '../user';
// L'assertion d'une promesse doit être retournée.
it('works with promises', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toBe('Mark'));
});
Nous appelons jest.mock('../request')
pour dire à Jest d'utiliser notre simulateur manuel. it
s'attend à ce que la valeur de retour soit une promesse qui va être 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 un moyen moins verbeux utilisant resolves
pour décortiquer la valeur d'une promesse remplie avec tout autre comparateur. 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
L'écriture de tests utilisant la syntaxe async
/await
est également possible. Voici comment écrire les mêmes exemples que précédemment :
// async/wait peut être utilisé.
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
.