Jest + TypeScript로 의존성 조롱하기

다음과 같은 문구를 들은 적이 있습니다.

Pure applications can only heat machines



그리고 음... 그것은 사실입니다. 실생활에서 애플리케이션의 일부는 외부 세계와 접촉해야 하고 순수하지 않아야 하며 이를 테스트하는 것은 까다로울 수 있습니다.

wait, what are (im)pure functions and side effects?



문맥



한 가지 일반적인 용도는 애플리케이션에 대한 설정feature flags입니다. 다음 기능이 있다고 상상해보십시오.

// file.ts
import { getFlag } from 'some-lib/flags'

export const myInpureFunction = () => {
  const flag = getFlag('flagName') as boolean
  return flag
    ? "this aplication is flagged"
    : "this application is not flagged"
}


그리고 그것을 테스트해야 합니다. 결국 기능 플래그가 프로젝트에서 예상한 대로 작동하는지 확인해야 합니다. 문제는 이getFlag 함수와 그 값이 변경될 때 발생하는 상황을 조롱해야 한다는 것입니다.

음... 그럼 문제가 뭐죠?

함수/모듈을 조롱하는 일반적인 방법은 다음과 같습니다.

// file.spec.ts

jest.mock('some-lib/flags', ()=>({
  getFlag: () => true // or false or any other value
})


그러나 테스트로 다룰 두 가지 컨텍스트가 있습니다.

// file.spec.ts

describe('when feature flag is on', () => {...})

describe('when feature flag is off', () => {...})


그리고 getFlag 모형을 변경해야 합니다.

JavaScript에서는 다음과 같은 솔루션을 구현할 수 있습니다.

// file.spec.ts
import { getFlag } from 'some-lib/flags'

jest.mock('some-lib/flags')

describe('when feature flag is on', () => {
  getFlag.mockReturnValue(true)
  //...
})


또는 mockImplementation를 사용하지만 TypeScript에서는 이들 중 어느 것도 허용되지 않습니다.

나는 다음과 같은 유사한 솔루션을 보았습니다.

// file.spec.ts
import * as flags from 'some-lib/flags'

jest.mock('some-lib/flags')

describe('when feature flag is on', () => {
  flags.getFlag = jest.fn()
  //...
})


그러나 TypeScript는 이것도 허용하지 않습니다.



해결책



방법이 있습니다.

현명한 Type Assertion의 비극을 경험한 적이 있습니까?



제 생각에는 이것은 매우 직관적인 솔루션은 아니지만 일단 보고 나면 이해하기 쉽습니다.

// file.spec.ts
import { getFlag } from 'some-lib/flags'

jest.mock('some-lib/flags')

describe('when feature flag is on', () => {
  beforeEach(() => {
    (getFlag as jest.Mock).mockReturnValueOnce(true);
  });

  //...
})


이름 getFlagjest.Mock 유형으로 지정하면 mockReturnValueOnce 와 같은 jest 모의 함수를 사용할 수 있습니다.

이 경우 이describe 내부의 모든 테스트는 우리 모의의 true 값을 사용합니다. beforeEach 블록 안에 넣으면 무슨 일이 일어나고 있는지 더 잘 제어하고 읽을 수 있다고 생각합니다. it도 차단합니다.

구현이나 반환을 모의하는 대신 mockReturnValueOnce를 사용하는 것은 변경 사항이 다른 테스트에 영향을 미치지 않기 때문에 좋은 습관입니다. 테스트의 부작용에 매우 주의하십시오. 테스트가 때때로 적합하고 때로는 적합하지 않은 이유를 찾는 데 어려움을 겪을 수 있습니다. '티.

잘,

나는 이것이 당신에게 유용하기를 바랍니다 :)



안전하고, 집에 있고, 마스크를 쓰고, Emacs를 사용하세요(Emacs 텍스트는 아니지만 하하)
키스와 포옹

좋은 웹페이지 즐겨찾기