😊
JestでiframeのpostMessage呼び出しのテストをしてみる
自分はあまりテストに精通しているわけではないので、実装するよりもテストを書く方が時間がかかる。
それでも、テストがあることでそのアプリケーションの仕様を自然な形で示すことができるので、書かないわけにはいかない。
やりたいこと
- 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