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
Patricia ArquetteOriginal
2024-12-30 13:50:10945Durchsuche

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()
};

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,
    );
  },
});

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",
    }
  `);
});

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,
      );
    },
  };
};

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

expect.addSnapshotSerializer(replaceProperty('id', '[ID]'));
expect.addSnapshotSerializer(replaceProperty('createdAt', '[TIMESTAMP]'));

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

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!

Stellungnahme:
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
Vorheriger Artikel:API-Integration verstehenNächster Artikel:API-Integration verstehen