どういうことか?
JestでonChangeイベントを発火させることが出来るfireEvent.changeというメソッドがあります。このメソッドには引数としてHTMLInputElementインターフェースのオブジェクトと、そのElementに設定する値をセットすることが出来ます。
fireEvent.changeメソッド
fireEvent.change(input, { target: { value: 15 } })
実はこのメソッドでHTMLInputElementがnumberタイプのように入力値に制限がかかっている要素であっても、文字列をセットすることが出来てしまいます。
// inputのtypeはnumber
fireEvent.change(input, { target: { value: '15' } }) // 値の変更可
再レンダリングされる際にはこの値はnumberタイプの使用に則って処理されます
発生する問題
この仕様(?)はこのコード以降に書かれるJestのテストコードで問題を発生させてしまいます。この状態のchangeメソッドを実行すると再レンダリングするまで、inputの値が文字列になってしまいます。つまり数字としてマッチングしても失敗してしまいます。
文字列なので失敗する
render(<input type="number" data-testid="testtest" />, container)
const input = screen.getByTestId('testtest') as HTMLInputElement
fireEvent.change(input, { target: { value: '5' } })
expect(input.value).toBe(5) // 失敗
expect(input.value).toBe('5') // 逆にtype=numberなのに文字列でマッチに成功する
初歩的なミスですが、inputのtypeがnumberなのにテストのマッチが文字列で成功になってしまいます。私はこの問題のる原因を見つけるのに苦労しました。
対策
基本的には型を間違えることはないと思いますが、本来セットすることができる型以外でマッチが成功してしまう上に、現状エラーにもならずコンパイラで弾いてもくれないので、このメソッドを使用するときは値を変更するinput要素のtypeを必ず確認して、セットする値の型を間違えないように注意するようにしましょう。
まだ確認していませんが他のfireEventのメソッドにも同じような問題が発生しているかもしれません。もし見つけましたらまた記事にします。