Jest est excellent pour se moquer des importations en javascript/typescript, mais j'ai beaucoup de mal à me souvenir des détails de l'implémentation.
Les fonctions et les objets doivent être simulés de différentes manières, les exportations par défaut sont simulées de manière subtilement différente des exportations nommées, et Jest ne fonctionne pas particulièrement bien avec TypeScript. Combinez toutes ces choses et il peut être difficile d'élaborer, ou même de rechercher, la bonne approche pour votre scénario moqueur.
J'ai créé ce guide pour répondre à la question "Comment puis-je me moquer de mon importation ?" quelle que soit cette importation. Par défaut ou nommé, fonction ou objet.
J'ai testé toutes ces approches en utilisant les versions de logiciels suivantes :
Et avec un fichier jest.config.js minimal par défaut :
export default { testEnvironment: 'node', transform: { '^.+.tsx?$': ['ts-jest', {}], }, testMatch: ['**/*.test.ts'], };
Les importations largement courantes se répartissent en deux catégories dont nous pourrions vouloir nous moquer :
Nous les aborderons tour à tour, en commençant par les fonctions.
Les fonctions exportées à partir des modules peuvent être nommées ou par défaut. Nous examinerons les deux. Premièrement :
Cela devrait être utilisé pour simuler une fonction exportée nommée à partir d'un module, quelque chose comme ceci :
// ./path/to/module.ts export function doSomething(...) { ... }
On peut se moquer de cette façon :
import { doSomething } from './path/to/module'; // note: This should be the path to the module from the test file, // NOT from the module that contains the doSomething function itself. jest.mock('./path/to/module', () => ({ doSomething: jest.fn(), })); ... it('should do something', () => { // We need to assert that the function is a jest.Mock // so that typescript will allow us to call mock methods. (doSomething as jest.Mock).mockReturnValue(mockValue); // run your test here expect(doSomething).toHaveBeenCalledTimes(1); // etc. });
Cela devrait être utilisé pour simuler une fonction qui est l'exportation par défaut d'un module, quelque chose comme ceci :
// ./path/to/module.ts export default function doSomething(...) { ... }
Il est moqué de la même manière que les exportations nommées :
import doSomething from './path/to/module' jest.mock('./path/to/module', () => ({ __esModule: true, default: jest.fn() })) ... it('should do something', () => { (doSomething as jest.Mock).mockResolvedValue(mockData); // Run your test here expect(doSomething).toHaveBeenCalledTimes(5); });
Il existe quelques variantes à prendre en compte lors de la simulation d'un objet exporté (qu'il s'agisse d'une classe, d'un objet json ou autre).
Si vous avez juste besoin de vous moquer de propriétés (un fichier de configuration par exemple), pas de méthodes, alors voici comment procéder :
import config from '../config'; jest.mock('../config', () => ({ __esModule: true, default: { apiKey: '123MockKey', ... }, })); ... it('Should do something', () => { ... });
Et si les propriétés simulées doivent varier selon le test :
import config from '../config'; const mockConfig = { apiKey: '123MockKey', ... }; jest.mock('../config', () => ({ __esModule: true, default: mockConfig, })); ... beforeEach(() => { // restore defaults before each test mockConfig.apiKey = '123MockKey'; ... }); it('Should do something', () => { mockConfig.apiKey = 'new value'; // rest of the test }); // more tests
Très similaire aux objets d'exportation par défaut moqueurs :
import { config } from '../config'; const mockConfig = { apiKey: '123MockKey', ... }; jest.mock('../config', () => ({ config: mockConfig, })); // the rest is exactly the same as when mocking a default export object.
Lorsqu'un objet avec des méthodes est exporté (nommé ou par défaut) à partir d'un module et que nous devons nous moquer de la sortie de ces méthodes, l'approche est légèrement différente.
Étant donné un cours :
// ./path/to/module.ts class ComplicatedThing { // properties, fields, constructor etc. go here getData() { ... } ... } // note: I don't necessarily recommend exporting an instance // of a class like this - purely illustrative for testing purposes. // https://medium.com/@lazlojuly/are-node-js-modules-singletons-764ae97519af export const complicatedThing = new ComplicatedThing(...);
Et pour se moquer de notre objet exporté :
export default { testEnvironment: 'node', transform: { '^.+.tsx?$': ['ts-jest', {}], }, testMatch: ['**/*.test.ts'], };
Se moquer d'un objet d'export par défaut est exactement la même chose sauf lorsque nous définissons le mock :
// ./path/to/module.ts export function doSomething(...) { ... }
C'est pour se moquer d'un objet qui n'est pas directement importé dans un module que vous testez, mais qui est plutôt transmis en tant que paramètre à une classe/fonction.
Remarque : Si vous vous moquez d'une classe, vous souhaiterez peut-être plutôt créer une interface et créer une implémentation simulée de celle-ci à transmettre à votre fonction/classe. Cela vous évitera d'avoir à faire des manigances d'affirmation de type inélégantes comme ci-dessous.
import { doSomething } from './path/to/module'; // note: This should be the path to the module from the test file, // NOT from the module that contains the doSomething function itself. jest.mock('./path/to/module', () => ({ doSomething: jest.fn(), })); ... it('should do something', () => { // We need to assert that the function is a jest.Mock // so that typescript will allow us to call mock methods. (doSomething as jest.Mock).mockReturnValue(mockValue); // run your test here expect(doSomething).toHaveBeenCalledTimes(1); // etc. });
// ./path/to/module.ts export default function doSomething(...) { ... }
import doSomething from './path/to/module' jest.mock('./path/to/module', () => ({ __esModule: true, default: jest.fn() })) ... it('should do something', () => { (doSomething as jest.Mock).mockResolvedValue(mockData); // Run your test here expect(doSomething).toHaveBeenCalledTimes(5); });
J'espère que cela vous sera utile, ainsi qu'à moi-même, la prochaine fois que j'aurai du mal à me souvenir des détails sur la façon de se moquer des importations en dactylographié.
J'espère qu'il pourra couvrir tous vos besoins de moquerie simples et vous donner un point de départ pour vous moquer d'importations plus complexes.
Merci d'avoir lu.
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!