Sassyブログ

好きなことで暮らしを豊かにするブログ

jest v27.2.0へのアップデートで発生した不具合の回避方法について

f:id:y_saiki:20210917092619p:plain

問題

仕事先ではRnovateを使用して週1でライブラリのアップデートを行っています。

Renovateって何?って方はこちらから

www.whitesourcesoftware.com

メジャーバージョンアップ時はその対象のモジュール単体で、マイナーバージョンアップ時はその週に更新された依存モジュールを

まとめてPRを作成して開発者が確認を行いライブラリのメンテナンスを行っています。

ついこの間マイナーバージョンアップでPRが作成されていたので確認したところ、テストが失敗してました。

その中にはjest v27.1.0→v27.2.0へのアップデート含まれており、エラーが発生していたので内容を確認したところ以下2件のエラーメッセージが表示されていました。

まず1つ目

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app

そして2つ目

thrown: “Exceeded timeout of 10000 ms for a test.

リリースノートを確認しましたが関連しそうな内容の記載が見つからなく、原因がわからないままでした。

2021/9/17時点で確認された不具合

github.com

github.com

2件のPRに目を通すとやはり2件のエラーに関連する内容が記載されていました。

原因

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)

  2. You might be breaking the Rules of Hooks

  3. You might have more than one copy of React in the same app

の内容は、https://github.com/facebook/jest/issues/11873 に該当しそう上記の1〜3のケースだとおそらく3が該当しそうですね。

issueにも記載されておりますが、

seems how mocks are applied changed between 27.1.0 and 27.1.1.

27.1.1でモックの適用方法が変わったらしく、jest.isolateModuelsが返すモックのインスタンスがテスト内のモックのインスタンスと異なるようです。

すでに修正PRが出されています。

github.com

あとはこちらの解決を待ちましょう。

もう一つの

thrown: “Exceeded timeout of 10000 ms for a test.

については、https://github.com/facebook/jest/issues/11876 しそうで、jest.useFakeTimersを使っている場合、

テストで複数の非同期関数の結果を待つテストを作成していると非同期結果が返って来なくてテストに失敗するというものです。

こちらはまだ修正PRが確認されていないので作成されるまで待ちですね。。。

対処方法

しかし、このままでは他のライブラリの更新が行えないままとなってしまうので、

対応としてはjestのパッケージが依存するモジュールであり不具合が関連するjest-runtimeのみのバージョンを以前のバージョン(v27.1.0)に戻してテストが通る状態することで、他のライブラリのバージョンをあげられるように対応しました。

そのため以下の設定をpackage.jsonに追記します。

“jest/**/jest-runtime”: “27.1.0"

yarnのresolutionsを使用して依存パッケージのさらに依存のさらに依存の〜バージョンをコントロールすることができます。

キーは依存関係を表しています。

なのでjest/**の部分は「jestの依存の依存の依存の〜に入っている全ての」というような感じになっており、最後にパッケージを指定しています。

値にはバージョンを記載することで、package.json側の記述によらずそのバージョンを使うようにしてくれます。

yarnのresolutionsについてはこちら