Aller au contenu principal
Version: 27.2

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.

user.js
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 :

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.
// 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 :

__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: 'Utilisateur avec ' + userID + ' non trouvé.',
}),
);
});
}

Maintenant, écrivons un test pour notre fonctionnalité asynchrone.

__tests__/user-test.js
jest.mock('../request');
import * as user from '../user';
// The assertion for a promise must be returned.
it('fonctionne avec des promesses', () => {
expect.assertions(1);
return user.getUserName(4).then(data => expect(data).toEqual('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('fonctionne avec resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toEqual('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('fonctionne avec async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toEqual('Mark');
});
// async/await peut aussi être utilisé avec `.resolves`.
it('fonctionne avec async/await et resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toEqual('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 traitées en utilisant la méthode .catch. Assurez-vous de rajouter expect.assertions pour vérifier qu'un certain nombre d'assertions sont appelées. Sinon une promesse accomplie ne passerait pas le test :

// Tests d'erreurs asynchrones en utilisant Promise.catch.
it('teste l'erreur avec des promesses', () => {
expect.assertions(1);
return user.getUserName(2).catch(e =>
expect(e).toEqual({
error: 'Utilisateur avec 2 non trouvé.',
}),
);
});
// Ou en utilisant async/await.
it('teste l'erreur avec async/await', async () => {
expect.assertions(1);
try {
await user.getUserName(1);
} catch (e) {
expect(e).toEqual({
error: 'Utilisateur avec 1 non trouvé.',
});
}
});

.rejects#

La fonction .rejects fonctionne comme la fonction .resolves. Si la promesse est accomplie, le test échoue 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 par ailleurs facile d'oublier de return/await les assertions .resolves.

// Tests d'erreurs asynchrones en utilisant `.rejects`.
it('teste l'erreur avec rejects', () => {
expect.assertions(1);
return expect(user.getUserName(3)).rejects.toEqual({
error: 'Utilisateur avec 3 non trouvé.',
});
});
// Ou en utilisant async/await avec `.rejects`.
it('teste l'erreur avec async/await et rejects', async () => {
expect.assertions(1);
await expect(user.getUserName(3)).rejects.toEqual({
error: 'Utilisateur avec 3 non trouvé.',
});
});

The code for this example is available at examples/async.

Si vous souhaitez tester les minuteurs, comme setTimeout, jetez un coup d'œil à la documentation simulateurs de temporisation.