Maison > interface Web > js tutoriel > Se moquer avec Jest et dactylographié - une aide-mémoire

Se moquer avec Jest et dactylographié - une aide-mémoire

Barbara Streisand
Libérer: 2024-12-22 22:31:11
original
602 Les gens l'ont consulté

Mocking with Jest and typescript - a cheatsheet

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.

Mon environnement

J'ai testé toutes ces approches en utilisant les versions de logiciels suivantes :

  • nœud v22.11.0
  • blague v29.7.0
  • ts-jest v29.2.5
  • @types/jest v29.5.14

Et avec un fichier jest.config.js minimal par défaut :

export default {
  testEnvironment: 'node',
  transform: {
    '^.+.tsx?$': ['ts-jest', {}],
  },
  testMatch: ['**/*.test.ts'],
};
Copier après la connexion
Copier après la connexion

Importations moqueuses

Les importations largement courantes se répartissent en deux catégories dont nous pourrions vouloir nous moquer :

  • fonctions
  • objets

Nous les aborderons tour à tour, en commençant par les fonctions.

Fonctions d'importation

Les fonctions exportées à partir des modules peuvent être nommées ou par défaut. Nous examinerons les deux. Premièrement :

Se moquer d'une fonction exportée nommée à partir d'un module

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(...) {
  ...
}
Copier après la connexion
Copier après la connexion

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.
});
Copier après la connexion
Copier après la connexion

Se moquer de la fonction par défaut renvoyée par un module

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(...) {
  ...
}
Copier après la connexion
Copier après la connexion

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);
});
Copier après la connexion
Copier après la connexion

Importer des objets

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).

  • Est-ce une exportation nommée ou par défaut ?
  • A-t-il des méthodes dont nous souhaitons également nous moquer, ou simplement des propriétés ?

Se moquer des objets par défaut sans méthodes

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', () => {
  ...
});
Copier après la connexion

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
Copier après la connexion

Se moquer des objets d'exportation nommés sans méthodes

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.
Copier après la connexion

Se moquer d'un objet avec des méthodes

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(...);
Copier après la connexion

Et pour se moquer de notre objet exporté :

export default {
  testEnvironment: 'node',
  transform: {
    '^.+.tsx?$': ['ts-jest', {}],
  },
  testMatch: ['**/*.test.ts'],
};
Copier après la connexion
Copier après la connexion

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(...) {
  ...
}
Copier après la connexion
Copier après la connexion

Bonus : Méthodes moqueuses sur un objet passé directement à une fonction/classe de test en paramètre

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.
});
Copier après la connexion
Copier après la connexion
// ./path/to/module.ts

export default function doSomething(...) {
  ...
}
Copier après la connexion
Copier après la connexion
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);
});
Copier après la connexion
Copier après la connexion

Conclusion

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!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal