😊

JestでiframeのpostMessage呼び出しのテストをしてみる

2022/08/16に公開

自分はあまりテストに精通しているわけではないので、実装するよりもテストを書く方が時間がかかる。
それでも、テストがあることでそのアプリケーションの仕様を自然な形で示すことができるので、書かないわけにはいかない。

やりたいこと

  • iframeのpostMessageが呼び出されていること
  • iframeのpostMessageが正しい引数で呼び出されていること

状況

  • iframeはexportしていない関数の中で生成している
  • iframeの参照もexportしていない関数で行っている
    という感じなので、テストのためだけに関数を切り出してscopeを広くするのはいけてないので、対応策を考えた。

やったこと

最初はgetElementByIdをmock化しようと思ったがうまくいかなかったし、どこで使われているかがわからないのでやめた。
そして以下のようにすることで対応した。

const frameId = 'iframe-id'
  document.body.innerHTML = `
    <iframe id="${frameId}"></iframe>
  `
  const frame = document.getElementById(frameId) as HTMLIFrameElement
  expect(frame.contentWindow).toBeTruthy()
  const postMessageSpy = jest.spyOn(frame.contentWindow!, 'postMessage')

あらかじめiframeをinnerHTMLに差し込んでiframeを取得し、jest.spyOnでpostMessageを監視する。
これにより最後のpostMessageSpyを使うことで、以下のようにテストすることができる

 expect(postMessageSpy.mock.calls).toHaveLength(1)
 expect(postMessageSpy).toHaveBeenCalledWith(params)

Discussion