Maison > interface Web > js tutoriel > Comment supprimer les valeurs dynamiques d'un instantané avec des sérialiseurs

Comment supprimer les valeurs dynamiques d'un instantané avec des sérialiseurs

Patricia Arquette
Libérer: 2024-12-30 13:50:10
original
950 Les gens l'ont consulté

How To Remove Dynamic Values From Snapshot With Serializers

Les tests instantanés dans Jest et Vitest sont des outils puissants pour détecter les changements inattendus dans la sortie de votre code. Cependant, ils se cassent facilement lorsqu'il s'agit de valeurs dynamiques telles que des identifiants générés ou des horodatages qui changent à chaque exécution de test. Bien que se moquer de ces valeurs soit possible, cela peut entraîner des effets secondaires involontaires.

Considérez cet objet utilisateur qui pourrait être renvoyé par un appel API ou une requête de base de données :

const user = {
  id: crypto.randomUUID(),
  name: "John Doe",
  createdAt: new Date().toISOString()
};
Copier après la connexion

Chaque fois que vous exécutez vos tests, les valeurs id etcreatedAt seront différentes, provoquant l'échec de vos instantanés.

Implémentation de base

Voici comment créer un sérialiseur personnalisé qui remplace les valeurs dynamiques par des espaces réservés cohérents :

const property = 'id';
const placeholder = '[ID]';

expect.addSnapshotSerializer({
  test(val) {
    return val && typeof val === 'object' && Object.hasOwn(val, property) && val[property] !== placeholder
  },
  serialize(val, config, indentation, depth, refs, printer) {
    return printer(
      {
        ...(val as Record<string, unknown>),
        [property]: placeholder,
      },
      config,
      indentation,
      depth,
      refs,
    );
  },
});
Copier après la connexion

Vous pouvez ajouter un sérialiseur d'instantanés personnalisé avec expect.addSnapshotSerializer().
Il attend un objet avec deux fonctions :

  • test() est utilisé pour déterminer si ce sérialiseur personnalisé doit être utilisé. Il vérifie si la valeur de expect(value) est un objet avec la propriété et n'a pas été remplacée par l'espace réservé.

  • serialize() n'est appelé que si test() a renvoyé true. Il remplace la propriété par l'espace réservé et appelle la fonction Printer() pour sérialiser la valeur dans une chaîne de type JSON.

Essais

Maintenant, lorsque vous exécuterez vos tests, vous verrez que l'identifiant a été remplacé par l'espace réservé [ID] :

interface User {
  id: string;
  name: string;
  createdAt: string;
}

expect.addSnapshotSerializer({ /* ... */ });

test('snapshot', () => {
  const user: User = {
    id: '123e4567-e89b-12d3-a456-426614174000',
    name: 'John Doe',
    createdAt: '2024-03-20T12:00:00Z',
  };

  expect(user).toMatchInlineSnapshot(`
    {
      "id": "[ID]",
      "name": "John Doe",
    }
  `);
});
Copier après la connexion

Le rendre réutilisable

Et si nous devons gérer plusieurs propriétés dynamiques ? Créons une solution réutilisable :

export const replaceProperty = (
  property: string,
  placeholder: string,
): SnapshotSerializer => {
  return {
    test(val) {
      return val && typeof val === 'object' && Object.hasOwn(val, property) && val[property] !== placeholder
    },
    serialize(val, config, indentation, depth, refs, printer) {
      return printer(
        {
          ...(val as Record<string, unknown>),
          [property]: placeholder,
        },
        config,
        indentation,
        depth,
        refs,
      );
    },
  };
};
Copier après la connexion

Dans vos tests, vous pouvez créer plusieurs sérialiseurs pour différentes propriétés :

expect.addSnapshotSerializer(replaceProperty('id', '[ID]'));
expect.addSnapshotSerializer(replaceProperty('createdAt', '[TIMESTAMP]'));
Copier après la connexion

J'utilise ces sérialiseurs si fréquemment que j'ai créé le package npm snapshot-serializers pour faciliter la tâche de tout le monde.

import { replaceProperty, removeProperty } from 'snapshot-serializers';

type User = {
  id: string;
  name: string;
  createdAt: string;
  password?: string;
};

// Type-safe property replacement
expect.addSnapshotSerializer(
  // TypeScript will only allow "id" | "name" | "createdAt" | "password"
  replaceProperty<User>({
    property: 'id',
    placeholder: '[ID]'
  })
);

// Remove properties entirely
expect.addSnapshotSerializer(
  removeProperty<User>({
    property: 'password'
  })
);

// This would cause a TypeScript error:
expect.addSnapshotSerializer(
  replaceProperty<User>({
    property: 'invalid' // Error: Type '"invalid"' is not assignable...
  })
);
Copier après la connexion

Il fournit une API de type sécurisé pour remplacer ou supprimer des propriétés dans vos instantanés. Vous pouvez fournir un paramètre de type générique tel que removeProperty() et la fonction suggérera tous les noms de propriétés possibles en fonction du type d'utilisateur. Toute autre propriété provoquera une erreur TypeScript.

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