>웹 프론트엔드 >JS 튜토리얼 >직렬 변환기를 사용하여 스냅샷에서 동적 값을 제거하는 방법

직렬 변환기를 사용하여 스냅샷에서 동적 값을 제거하는 방법

Patricia Arquette
Patricia Arquette원래의
2024-12-30 13:50:101012검색

How To Remove Dynamic Values From Snapshot With Serializers

Jest 및 Vitest의 스냅샷 테스트는 코드 출력에서 ​​예기치 않은 변경 사항을 감지하는 강력한 도구입니다. 그러나 생성된 ID나 각 테스트 실행 시 변경되는 타임스탬프와 같은 동적 값을 처리할 때 쉽게 중단됩니다. 이러한 값을 조롱하는 것은 가능하지만 의도하지 않은 부작용이 발생할 수 있습니다.

API 호출이나 데이터베이스 쿼리에서 반환될 수 있는 다음 사용자 개체를 고려해보세요.

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

테스트를 실행할 때마다 id 및 CreateAt 값이 달라져 스냅샷이 실패하게 됩니다.

기본 구현

동적 값을 일관된 자리 표시자로 바꾸는 사용자 정의 직렬 변환기를 만드는 방법은 다음과 같습니다.

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

expect.addSnapshotSerializer()를 사용하여 사용자 정의 스냅샷 직렬 변환기를 추가할 수 있습니다.
두 가지 기능을 가진 객체가 필요합니다:

  • test()는 이 사용자 정의 직렬 변환기를 사용해야 하는지 여부를 결정하는 데 사용됩니다. Expect(value)의 값이 속성을 가진 객체이고 자리 표시자로 대체되지 않았는지 확인합니다.

  • serialize()는 test()가 true를 반환한 경우에만 호출됩니다. 속성을 자리 표시자로 대체하고 프린터() 함수를 호출하여 값을 JSON과 같은 문자열로 직렬화합니다.

테스트

이제 테스트를 실행하면 id가 [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",
    }
  `);
});

재사용 가능하게 만들기

여러 동적 속성을 처리해야 하면 어떻게 되나요? 재사용 가능한 솔루션을 만들어 보겠습니다.

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

테스트에서 다양한 속성에 대해 여러 직렬 변환기를 생성할 수 있습니다.

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

저는 이 직렬 변환기를 너무 자주 사용하기 때문에 모든 사람이 더 쉽게 사용할 수 있도록 npm 패키지 스냅샷 직렬 변환기를 만들었습니다.

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

스냅샷의 속성을 대체하거나 제거할 수 있는 유형이 안전한 API를 제공합니다. RemoveProperty()와 같은 일반 유형 매개변수를 제공할 수 있으며 함수는 User 유형을 기반으로 가능한 모든 속성 이름을 제안합니다. 다른 속성을 사용하면 TypeScript 오류가 발생합니다.

위 내용은 직렬 변환기를 사용하여 스냅샷에서 동적 값을 제거하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:API 통합 이해다음 기사:API 통합 이해