DOM操作をするjQueryコードをJestでテストする方法を勉強した話

f:id:e125731:20211206173432p:plain

エキサイトホールディングス Advent Calendar 2021の10日目は、 エキサイト株式会社 エンジニアのあはれんがお送りします。

DOM操作をするjQueryコードをJestでテストするために、勉強としてJestのサンプルコードを動かしてみました。

その際に学んだ点、サンプルコードの実行方法を共有したいと思います。

Jestについて

Jestは、JavaScriptのコードの正しさを保証するために設計されたJavaScriptテスティングフレームワークです。 JavaScript単体で動作するのはもちろん、html要素を操作するものもテストすることができます。

jestjs.io

Jestの導入

Jestを導入するにはnpmまたはyarnが必要ですので、準備をお願いします。

npmの場合は以下のように実行してください。

npm install --save-dev jest

これだけで導入は完了です!簡単ですよね。

詳しい導入方法は、公式ドキュメントにありますのでそちらを参考ください。

jestjs.io

サンプルコードを動かしてみる

jestjs.io

上記のページで、JestでDOM操作する方法を説明しています。

また、サンプルコードを公開していますので、 サンプルコードをダウンロードして、実際に動作を確認することができます。

// 1. プロジェクトをダウンロードする
$ git clone git@github.com:facebook/jest.git
// 2. jQueryのサンプルコードがあるディレクトリに移動する
$ cd examples/jquery/
// 3. Jestを導入
$ npm install --save-dev jest
// 4. テストを実施
$ npm test

> example-jquery@0.0.0 test
> jest

 PASS  __tests__/display_user.test.js
 PASS  __tests__/fetch_current_user.test.js

Test Suites: 2 passed, 2 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        1.579 s
Ran all test suites.

では、サンプルコードを読んでみましょう。

f:id:e125731:20211204231902p:plain
(引用:https://jestjs.io/ja/docs/tutorial-jquery )

今回読むサンプルコードは、displayUser.jsをテスト対象としたコードです。

テストには、準備、実行、評価の3段階があります。

準備の段階では、 テスト対象のDOMとJavaScriptファイル(displayUser.js)を用意しています。 また、今回はテスト対象が別のJavaScriptファイル(fetchCurrentUser.js)を利用していたのでモックしています。 fetchCurrentUser.jsをモックすることでdisplayUser.jsの振る舞いのみをテストすることができます。

実行の段階では、jQueryを利用してユーザーが行うであろうクリック処理を実現させ、テストを実行しています。

テスト結果の評価では、モックでセットしたデータのJohnny Cash - Logged Inが表示されることを確認しています。

このようにして、DOM操作をするコードのテストを行うことができます。

サンプルコードから一歩進んでみる

サンプルコードの説明だけでは味気ないので、テストケースを1つ追加してみたいと思います。

fetchCurrentUser.jsから返ってくるデータのloggedInがfalseならば、Johnny Cash - Logged Outと表示されるか確認するテストケースを追加します。

f:id:e125731:20211204231950p:plain
ログアウト時の画面表示を確認するテストを追加

$ npm test

> example-jquery@0.0.0 test
> jest

 FAIL  __tests__/display_user.test.js
  ● displays a logout user after a click

    expect(received).toEqual(expected) // deep equality

    Expected: "Johnny Cash - Logged Out"
    Received: "  "

      62 |
      63 |   expect(fetchCurrentUser).toBeCalled();
    > 64 |   expect($('#username').text()).toEqual('Johnny Cash - Logged Out');
         |                                 ^
      65 | });
      66 |

      at Object.<anonymous> (__tests__/display_user.test.js:64:33)

 PASS  __tests__/fetch_current_user.test.js

Test Suites: 1 failed, 1 passed, 2 total
Tests:       1 failed, 3 passed, 4 total
Snapshots:   0 total
Time:        1.589 s
Ran all test suites.
zsh: exit 1     npm test

テスト実行結果は失敗してしまい、文字が表示されていないという結果になりました。

これは、1つ目のテストケースでfetchCurrentUser.jsjQuery等のモジュールがすでにrequireされているので、 2つ目のテストケースでrequireされないためです。

なので、毎回テストケースを実行する際に、requireするように、jest.resetModules()を呼び出す必要があります。

f:id:e125731:20211204231808p:plain
jest.restModulesを追記

上記を追記することでテストが成功するようになりました。

$ npm test

> example-jquery@0.0.0 test
> jest

 PASS  __tests__/display_user.test.js
 PASS  __tests__/fetch_current_user.test.js

Test Suites: 2 passed, 2 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.452 s
Ran all test suites.

最後に

Jestは、ReactやVue.js等のJavaScriptフレームワークのテストを書くためのフレームワークのイメージだったので、 DOMを操作するjQueryコードのテストもこんなに簡単に書けるとは思っていませんでした。

今後、jQueryコードを書く際は、Jestを使ってテストを書いていきたいと思います。

エキサイトホールディングスのアドベントカレンダーはまだまだ続きます。

明日の執筆担当は@Suzuki-Shuheiさんです。 引き続きお楽しみください。

採用情報はこちら↓

https://www.wantedly.com/companies/excite