Heim > Web-Frontend > js-Tutorial > So entfernen Sie dynamische Werte aus Snapshots mit Serialisierern

So entfernen Sie dynamische Werte aus Snapshots mit Serialisierern

Patricia Arquette
Freigeben: 2024-12-30 13:50:10
Original
977 Leute haben es durchsucht

How To Remove Dynamic Values From Snapshot With Serializers

Snapshot-Tests in Jest und Vitest sind leistungsstarke Tools zum Erkennen unerwarteter Änderungen in der Ausgabe Ihres Codes. Sie können jedoch leicht kaputtgehen, wenn es um dynamische Werte wie generierte IDs oder Zeitstempel geht, die sich bei jedem Testlauf ändern. Das Verspotten dieser Werte ist zwar möglich, kann aber zu unbeabsichtigten Nebenwirkungen führen.

Betrachten Sie dieses Benutzerobjekt, das von einem API-Aufruf oder einer Datenbankabfrage zurückgegeben werden könnte:

const user = {
  id: crypto.randomUUID(),
  name: "John Doe",
  createdAt: new Date().toISOString()
};
Nach dem Login kopieren

Jedes Mal, wenn Sie Ihre Tests ausführen, unterscheiden sich die Werte „id“ und „createdAt“, was dazu führt, dass Ihre Snapshots fehlschlagen.

Grundlegende Implementierung

So erstellen Sie einen benutzerdefinierten Serialisierer, der dynamische Werte durch konsistente Platzhalter ersetzt:

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,
    );
  },
});
Nach dem Login kopieren

Mit „expect.addSnapshotSerializer()“ können Sie einen benutzerdefinierten Snapshot-Serializer hinzufügen.
Es erwartet ein Objekt mit zwei Funktionen:

  • test() wird verwendet, um zu bestimmen, ob dieser benutzerdefinierte Serializer verwendet werden soll. Es prüft, ob der Wert von „expect(value)“ ein Objekt mit der Eigenschaft ist und nicht durch den Platzhalter ersetzt wurde.

  • serialize() wird nur aufgerufen, wenn test() true zurückgegeben hat. Es ersetzt die Eigenschaft durch den Platzhalter und ruft die Funktion „printer()“ auf, um den Wert in eine JSON-ähnliche Zeichenfolge zu serialisieren.

Tests

Wenn Sie jetzt Ihre Tests ausführen, werden Sie sehen, dass die ID durch den Platzhalter [ID] ersetzt wurde:

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",
    }
  `);
});
Nach dem Login kopieren

Wiederverwendbar machen

Was ist, wenn wir mehrere dynamische Eigenschaften verarbeiten müssen? Lassen Sie uns eine wiederverwendbare Lösung erstellen:

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,
      );
    },
  };
};
Nach dem Login kopieren

In Ihren Tests können Sie mehrere Serialisierer für verschiedene Eigenschaften erstellen:

expect.addSnapshotSerializer(replaceProperty('id', '[ID]'));
expect.addSnapshotSerializer(replaceProperty('createdAt', '[TIMESTAMP]'));
Nach dem Login kopieren

Ich verwende diese Serialisierer so häufig, dass ich die Snapshot-Serializer des NPM-Pakets erstellt habe, um es für alle einfacher zu machen.

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...
  })
);
Nach dem Login kopieren

Es bietet eine typsichere API zum Ersetzen oder Entfernen von Eigenschaften in Ihren Snapshots. Sie können einen generischen Typparameter wie „removeProperty()“ bereitstellen und die Funktion schlägt alle möglichen Eigenschaftsnamen basierend auf dem Benutzertyp vor. Jede andere Eigenschaft führt zu einem TypeScript-Fehler.

Das obige ist der detaillierte Inhalt vonSo entfernen Sie dynamische Werte aus Snapshots mit Serialisierern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage