Le contenu de cet article explique comment utiliser Jest pour tester JavaScript (fonction Mock). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Dans ce tutoriel, nous présenterons trois API liées aux fonctions Mock dans Jest, à savoir jest.fn(), jest.spyOn() et jest.mock(). Les utiliser pour créer des fonctions Mock peut nous aider à mieux tester certains des codes les plus logiquement complexes du projet, tels que les appels imbriqués de fonctions de test, les appels de fonctions de rappel, etc.
Si vous ne connaissez pas l'utilisation de base de Jest, veuillez d'abord lire : http://www.php.cn/js-tutorial-411835.html
Pourquoi utiliser la fonction Mock ?
Dans les projets, les méthodes d'un module appellent souvent les méthodes d'un autre module. Dans les tests unitaires, nous n'avons peut-être pas besoin de nous soucier du processus d'exécution et des résultats de la méthode appelée en interne, nous voulons simplement savoir si elle est appelée correctement et même spécifier la valeur de retour de la fonction. À l’heure actuelle, il est très nécessaire d’utiliser la fonction Mock.
Les trois fonctionnalités suivantes fournies par la fonction Mock sont très utiles lorsque nous écrivons du code de test :
Capturer les appels de fonction
Définir la valeur de retour de la fonction
Modifier l'implémentation interne de la fonction
On utilise ensuite la structure de répertoires de l'article précédent, en test /functions Écrivez le code de test dans le fichier .test.js et écrivez le code testé dans le répertoire src/.
1. jest.fn()
jest.fn() est le moyen le plus simple de créer une fonction Mock si l'implémentation interne de la fonction n'est pas définie. , jest.fn () renverra undefined comme valeur de retour.
// functions.test.js test('测试jest.fn()调用', () => { let mockFn = jest.fn(); let result = mockFn(1, 2, 3); // 断言mockFn的执行后返回undefined expect(result).toBeUndefined(); // 断言mockFn被调用 expect(mockFn).toBeCalled(); // 断言mockFn被调用了一次 expect(mockFn).toBeCalledTimes(1); // 断言mockFn传入的参数为1, 2, 3 expect(mockFn).toHaveBeenCalledWith(1, 2, 3); })
La fonction Mock créée par jest.fn() peut également définir une valeur de retour, définir une implémentation interne ou renvoyer un objet Promise.
// functions.test.js test('测试jest.fn()返回固定值', () => { let mockFn = jest.fn().mockReturnValue('default'); // 断言mockFn执行后返回值为default expect(mockFn()).toBe('default'); }) test('测试jest.fn()内部实现', () => { let mockFn = jest.fn((num1, num2) => { return num1 * num2; }) // 断言mockFn执行后返回100 expect(mockFn(10, 10)).toBe(100); }) test('测试jest.fn()返回Promise', async () => { let mockFn = jest.fn().mockResolvedValue('default'); let result = await mockFn(); // 断言mockFn通过await关键字执行后返回值为default expect(result).toBe('default'); // 断言mockFn调用后返回的是Promise对象 expect(Object.prototype.toString.call(mockFn())).toBe("[object Promise]"); })
Le code ci-dessus est constitué de plusieurs API et déclarations d'assertion couramment utilisées fournies par jest.fn(). Ci-dessous, nous écrivons du code testé dans le fichier src/fetch.js pour nous rapprocher de la manière commerciale. pour comprendre l'application pratique de la fonction Mock.
Le code testé s'appuie sur axios, une bibliothèque de requêtes couramment utilisée, et JSONPlaceholder, une interface de requête gratuite mentionnée dans l'article précédent. Veuillez d'abord exécuter npm install axios --save dans le shell pour installer les dépendances.
// fetch.js import axios from 'axios'; export default { async fetchPostsList(callback) { return axios.get('https://jsonplaceholder.typicode.com/posts').then(res => { return callback(res.data); }) } }
Nous encapsulons une méthode fetchPostsList dans fetch.js, qui demande l'interface fournie par JSONPlaceholder et renvoie la valeur de retour traitée via la fonction de rappel entrante. Si nous voulons tester que l'interface peut être demandée normalement, il nous suffit de constater que la fonction de rappel entrant peut être appelée normalement. Vous trouverez ci-dessous le code du test dans function.test.js.
import fetch from '../src/fetch.js' test('fetchPostsList中的回调函数应该能够被调用', async () => { expect.assertions(1); let mockFn = jest.fn(); await fetch.fetchPostsList(mockFn); // 断言mockFn被调用 expect(mockFn).toBeCalled(); })
2. jest.mock()
La méthode de requête encapsulée dans le dossier fetch.js ne peut pas être utilisée lorsque d'autres modules sont appelés. La requête est requise (la méthode de requête a dépassé un côté ou nécessite que la méthode renvoie des données non réelles). À l'heure actuelle, il est très nécessaire d'utiliser jest.mock() pour se moquer de l'ensemble du module.
Ensuite, nous créons un src/events.js dans le même répertoire que src/fetch.js.
// events.js import fetch from './fetch'; export default { async getPostList() { return fetch.fetchPostsList(data => { console.log('fetchPostsList be called!'); // do something }); } }
Le code de test dans function.test.js est le suivant :
// functions.test.js import events from '../src/events'; import fetch from '../src/fetch'; jest.mock('../src/fetch.js'); test('mock 整个 fetch.js模块', async () => { expect.assertions(2); await events.getPostList(); expect(fetch.fetchPostsList).toHaveBeenCalled(); expect(fetch.fetchPostsList).toHaveBeenCalledTimes(1); });
Dans le code de test, nous utilisons jest.mock('../src/fetch.js ' ) pour se moquer de l'intégralité du module fetch.js. Si vous commentez cette ligne de code, le message d'erreur suivant apparaîtra lors de l'exécution du script de test
De cette erreur, nous pouvons tirer un important conclusion :
Si vous souhaitez capturer le statut d'appel d'une fonction en plaisantant, la fonction doit être moquée ou espionnée !
3. La méthode jest.spyOn()
jest.spyOn() crée également une fonction fictive, mais cette fonction simulée peut non seulement capturer l'état d'appel du fonction, mais aussi La fonction espionnée peut être exécutée normalement. En fait, jest.spyOn() est un sucre syntaxique pour jest.fn(), qui crée une fonction simulée avec le même code interne que la fonction espionnée.
L'image ci-dessus est une capture d'écran du résultat d'exécution correct dans l'exemple de code précédent de jest.mock(). le script shell.log('fetchPostsList soit appelé!'); Cette ligne de code n'est pas imprimée dans le shell. En effet, après avoir passé jest.mock(), les méthodes du module ne seront pas réellement exécutées par jest. À ce stade, nous devons utiliser jest.spyOn().
// functions.test.js import events from '../src/events'; import fetch from '../src/fetch'; test('使用jest.spyOn()监控fetch.fetchPostsList被正常调用', async() => { expect.assertions(2); const spyFn = jest.spyOn(fetch, 'fetchPostsList'); await events.getPostList(); expect(spyFn).toHaveBeenCalled(); expect(spyFn).toHaveBeenCalledTimes(1); })
Après avoir exécuté npm run test, vous pouvez voir les informations imprimées dans le shell, indiquant que fetchPostsList a été exécuté normalement via jest.spyOn().
4.Résumé
Dans cet article, nous avons présenté jest.fn(), jest .mock. () et jest.spyOn() pour créer des fonctions fictives, nous pouvons mieux écrire notre code de test grâce aux trois fonctionnalités suivantes :
Capturer les appels de fonction
Définir la valeur de retour de la fonction
Modifier l'implémentation interne de la fonction
Dans les tests unitaires de projets réels, jest.fn() est souvent utilisé pour effectuer certains tests avec des fonctions de rappel ; jest.mock() peut se moquer des méthodes dans l'ensemble du module. le module a été couvert à 100% par les tests unitaires, il est nécessaire d'utiliser jest.mock() pour simuler le module afin de gagner du temps de test et de tester la redondance lorsque vous devez tester certaines méthodes qui doivent être entièrement exécutées, vous devez souvent les utiliser ; plaisanterie.spyOn(). Celles-ci obligent les développeurs à faire des choix flexibles basés sur le code métier réel.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!