Ein asynchrones Beispiel
Diese Seite wurde von PageTurner AI übersetzt (Beta). Nicht offiziell vom Projekt unterstützt. Fehler gefunden? Problem melden →
Aktiviere zunächst die Babel-Unterstützung in Jest, wie im Leitfaden Erste Schritte beschrieben.
Implementieren wir ein Modul, das Benutzerdaten von einer API abruft und den Benutzernamen zurückgibt.
import request from './request';
export function getUserName(userID) {
return request(`/users/${userID}`).then(user => user.name);
}
In dieser Implementierung erwarten wir, dass das request.js-Modul ein Promise zurückgibt. Wir verketten einen Aufruf von then, um den Benutzernamen zu erhalten.
Stell dir nun eine Implementierung von request.js vor, die über das Netzwerk geht und Benutzerdaten abruft:
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));
});
});
}
Da wir in unserem Test nicht auf das Netzwerk zugreifen wollen, erstellen wir ein manuelles Mock für unser request.js-Modul im Ordner __mocks__ (der Ordnername ist case-sensitive, __MOCKS__ funktioniert nicht). Es könnte etwa so aussehen:
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.`,
}),
);
});
}
Schreiben wir nun einen Test für unsere asynchrone Funktionalität.
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'));
});
Wir rufen jest.mock('../request') auf, um Jest mitzuteilen, dass es unser manuelles Mock verwenden soll. it erwartet, dass der Rückgabewert ein Promise ist, das aufgelöst wird. Du kannst beliebig viele Promises verketten und jederzeit expect aufrufen, solange du am Ende ein Promise zurückgibst.
.resolves
Es gibt eine weniger ausführliche Methode mit resolves, um den Wert eines erfüllten Promises zusammen mit anderen Matchern auszupacken. Wenn das Promise abgelehnt wird, schlägt die Assertion fehl.
it('works with resolves', () => {
expect.assertions(1);
return expect(user.getUserName(5)).resolves.toBe('Paul');
});
async/await
Das Schreiben von Tests mit der async/await-Syntax ist ebenfalls möglich. So würdest du dieselben Beispiele wie zuvor schreiben:
// 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');
});
Um async/await in deinem Projekt zu aktivieren, installiere @babel/preset-env und aktiviere die Funktion in deiner babel.config.js-Datei.
Fehlerbehandlung
Fehler können mit der .catch-Methode behandelt werden. Stelle sicher, dass du expect.assertions hinzufügst, um zu überprüfen, ob eine bestimmte Anzahl von Assertions aufgerufen wird. Andernfalls würde ein erfülltes Promise den Test nicht scheitern lassen:
// 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
Der .rejects-Helfer funktioniert wie der .resolves-Helfer. Wenn das Promise erfüllt wird, schlägt der Test automatisch fehl. expect.assertions(number) ist nicht erforderlich, wird aber empfohlen, um sicherzustellen, dass eine bestimmte Anzahl von Assertions während eines Tests aufgerufen wird. Es ist sonst leicht zu vergessen, die .resolves-Assertions mit return/await zu behandeln.
// 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.',
});
});
Der Code für dieses Beispiel ist unter examples/async verfügbar.
Wenn du Timer wie setTimeout testen möchtest, sieh dir die Dokumentation Timer-Mocks an.