>웹 프론트엔드 >JS 튜토리얼 >Jest와 TypeScript로 조롱하기 - 치트시트

Jest와 TypeScript로 조롱하기 - 치트시트

Barbara Streisand
Barbara Streisand원래의
2024-12-22 22:31:11552검색

Mocking with Jest and typescript - a cheatsheet

Jest는 javascript/typescript에서 import를 모의하는 데는 탁월하지만 구현 세부 사항을 기억하기가 매우 어렵습니다.

함수와 객체는 다양한 방식으로 모의해야 하며, 기본 내보내기는 명명된 내보내기와 미묘하게 다르게 모의되며, Jest는 TypeScript에서 특히 잘 작동하지 않습니다. 이러한 모든 사항을 결합하면 조롱 시나리오에 대한 올바른 접근 방식을 찾아내거나 검색하는 것이 어려울 수 있습니다.

저는 가져오기가 무엇이든 "가져오기를 어떻게 모의합니까?"라는 질문에 답하기 위해 이 가이드를 만들었습니다. 기본 또는 명명된 기능 또는 개체.

내 환경

다음 버전의 소프트웨어를 사용하여 이러한 접근 방식을 모두 테스트했습니다.

  • 노드 v22.11.0
  • jest v29.7.0
  • ts-jest v29.2.5
  • @types/jest v29.5.14

기본적으로 최소한의 jest.config.js 파일을 사용하면 다음과 같습니다.

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

모의 수입품

대체로 일반적인 import는 우리가 조롱할 수 있는 두 가지 범주로 분류됩니다.

  • 기능
  • 객체

기능부터 시작해서 두 가지를 차례로 다루겠습니다.

함수 가져오기

모듈에서 내보낸 함수에는 이름을 지정하거나 기본값을 지정할 수 있습니다. 우리는 두 가지를 모두 살펴보겠습니다. 첫 번째:

모듈에서 명명된 내보낸 함수 모의

다음과 같이 모듈에서 명명된 내보낸 함수를 모의하는 데 사용해야 합니다.

// ./path/to/module.ts

export function doSomething(...) {
  ...
}

다음과 같이 조롱할 수 있습니다.

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

모듈에서 반환된 기본 함수 모의

다음과 같이 모듈에서 기본 내보내기인 함수를 모의하는 데 사용해야 합니다.

// ./path/to/module.ts

export default function doSomething(...) {
  ...
}

명명된 내보내기와 유사하게 조롱됩니다.

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

개체 가져오기

내보낸 개체(클래스, json 개체 등)를 모의할 때 고려해야 할 몇 가지 변형이 있습니다.

  • 네임드 내보내기인가요 아니면 기본 내보내기인가요?
  • 모의하려는 메서드가 있나요, 아니면 속성만 있나요?

메소드 없이 기본 객체 모의

메서드가 아닌 속성(예: 구성 파일)을 모의해야 하는 경우 다음 방법을 사용하세요.

import config from '../config';

jest.mock('../config', () => ({
  __esModule: true,
  default: {
    apiKey: '123MockKey',
    ...
  },
}));

...

it('Should do something', () => {
  ...
});

모의 속성이 테스트마다 달라야 하는 경우:

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

메소드 없이 명명된 내보내기 객체 모의

기본 내보내기 개체를 모의하는 것과 매우 유사합니다.

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.

메소드를 사용하여 객체 모의

메서드가 있는 개체를 모듈에서 내보내고(이름이 지정되거나 기본값으로 지정됨) 해당 메서드의 출력을 모의해야 하는 경우 접근 방식이 약간 다릅니다.

수업:

// ./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(...);

내보낸 객체를 조롱하려면:

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

기본 내보내기 개체를 모의하는 것은 모의 개체를 정의할 때를 제외하고는 완전히 동일합니다.

// ./path/to/module.ts

export function doSomething(...) {
  ...
}

보너스: 테스트 함수/클래스에 매개변수로 직접 전달되는 객체에 대한 모의 메서드

테스트 중인 모듈로 직접 가져오지 않고 대신 클래스/함수에 매개변수로 전달되는 객체를 조롱하기 위한 것입니다.

참고: 클래스를 모의하는 경우 대신 인터페이스를 생성하고 해당 모의 구현을 생성하여 함수/클래스에 전달할 수도 있습니다. 이렇게 하면 아래와 같이 우아하지 않은 유형 어설션 헛소리를 할 필요가 없어집니다.

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.
});
// ./path/to/module.ts

export default function doSomething(...) {
  ...
}
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);
});

결론

이 내용이 여러분에게 도움이 되기를 바라며, 다음에 typescript에서 import를 모의하는 방법에 대한 세부 사항을 기억하려고 애쓰는 미래의 제 자신에게도 도움이 되기를 바랍니다.

이 문서가 간단한 모의 요구 사항을 모두 충족하고 더 복잡한 가져오기를 모의할 때 시작할 수 있는 장소를 제공할 수 있기를 바랍니다.

읽어주셔서 감사합니다.

위 내용은 Jest와 TypeScript로 조롱하기 - 치트시트의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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