0
TypeScript+JestでDateのモックをするときの型定義
2022-07-20

Jestでテストをする時の話、Dateをモックして特定の日付を返したいといったよくあるパターン

ちょうどGatsbyで作った本ブログのテストでも使用していて、エディタ上では赤くなっていたので対応しようと重い腰を上げた

  • もともと書いていたコード
beforeAll(() => {
  // 2021-03-10T15:00:00.000Z
  const mockDate = new Date(1615388400000)
  jest.spyOn(global, "Date").mockImplementation(() => mockDate)
})
  • 型のエラー内容
src/components/__tests__/archive.tsx:11:49 - error TS2345: Argument of type '() => Date' is not assignable to parameter of type '() => string'.
  Type 'Date' is not assignable to type 'string'.

11   jest.spyOn(global, "Date").mockImplementation(() => mockDate)

さっと調べるとでてくるstackoverflow、読んでみるとさまざまな解決方法があるよう

unit testing - jest typescript - Mock Date constructor - Stack Overflow

単純にas stringでキャストしようとするとそう簡単には許してくれない

src/components/__tests__/archive.tsx:13:31 - error TS2352: Conversion of type 'Date' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

13     .mockImplementation(() => mockDate as string)

このエラーにも書いてあるが「型が合いません、意図的なものならまずunknownにしてください」とのこと

結局下記のように書くことにした

jest.spyOn(global, "Date").mockImplementation(() => (mockDate as unknown) as string)

こういう回避方法があるのね…

一度unknownにキャストしてさらにstringにキャストすると

そもそもキャスト自体もあまり推奨されるやり方じゃないと思っていたが今回のケースではやむを得ず…

// @ts-ignoreで握りつぶすよりかは良いか…という感じ

2022-11-06追記

“@types/jest”: “29.2.2”,からこのハックは必要なくなった

使い続けていると怒られる

Argument of type '() => string' is not assignable to parameter of type '(value: string | number | Date) => Date'.

Dateを直接渡せるようになったみたい

0

Profile

swfz
swfz
日々学んだことを残していく
Today I Learned
コード片置き場

Account

RSS

Powered by Pixela
© 2024. swfz