Reactでコンポーネントの単体テストを試してみようと思いました。
それぞれコアとなるモジュールをインストールしただけでは動きませんでした。
調べてみると、コアのインストール以外にも他のモジュールを入れたり、設定を変えたりする必要がありました。
解決方法について記述します。
環境
Qiitaで公開されている、uryyyyyyy様のテストコードを参考にしています。
構成
前述したページの構成を参考にしつつ、現在のバージョンに合わせた構成にしています。
アプリケーションのコアになるモジュールの構成は次のようになっています。
モジュール名 | バージョン |
---|---|
react | 16.13.1 |
typescript | 4.0.2 |
webpack | 4.44.1 |
テスト用モジュール周り
テストのフレームワークはJasminにして、React用に構成を変えます。
モジュール名 | バージョン | 役割 |
---|---|---|
jasmine-core | 3.6.0 | テストフレームワーク |
enzyme | 3.11.0 | React用のテストユーティリティツール |
karma | 5.1.1 | テストランナー |
karma-chrome-launcher | 3.1.0 | KarmaのテストをChromeブラウザで実行するためのツール |
karma-jasmine | 4.0.1 | Karmaでjasminを使用するためのアダプタ |
karma-mocha-reporter | 2.2.5 | Karmaの実行結果をコンソールで表示する時に見やすくします |
karma-webpack | 4.0.2 | Webpack用のモジュール |
型定義周り
TypeScriptを使いますので、以下の型定義のモジュールをインストールします。
モジュール名 | バージョン |
---|---|
@types/enzyme | 3.10.5 |
@types/jasmine | 3.5.14 |
@types/react | 16.9.47 |
@types/react-dom | 16.9.8 |
ソース
処理の詳細について割愛しますが、Counter
というモジュールのテストを行います。
テスト内容は下記です。
- モジュールをレンダリング(描画)する
- モジュール内の指定したボタンをクリックする
テストファイルは、Counter.spec.tsx
と言う名前で用意しました。
// Counter.spec.tsx import * as React from 'react'; import { Counter } from '../Counter'; import { shallow } from 'enzyme'; import { CounterState } from '../module' import { ActionDispatcher } from '../Container' describe('Counter', () => { //...省略 })
【Tips】karmaのテスト実行ファイル
karmaのテスト内容は〇〇.spec.jsというファイルに記述します。
この記事では、TypeScriptを使用しますので、拡張子がts
やtsx
になります。
エラー内容
前項のテストファイルをkarmaで実行すると下記のエラーが発生します。
FAILED TESTS:
Counter
✖ rendering
Chrome 85.0.4183.83 (Mac OS xx.xx.xx)
Error:
Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To configure an adapter, you should callEnzyme.configure({ adapter: new Adapter() })
before using any of Enzyme's top level APIs, whereAdapter
is the adapter corresponding to the library currently being tested. For example:import Adapter from 'enzyme-adapter-react-15';
To find out more about this, see https://airbnb.io/enzyme/docs/installation/index.html
エラー内容を読む限り enzyme-adapter-react-15 というモジュール(アダプタ)が必要という事がわかりました。
修正方法
環境で記述したように、私の環境で使用するReactのバージョンは16系です。
前項では、バージョン15用モジュールを推奨していましたが、既に16用のモジュールも用意されています。
下記の手順に沿って導入します。
モジュールのダウンロード
Reactのバージョンが16.4以上の場合に使用するモジュールは、enzyme-adapter-react-16です。
下記のコマンドでモジュールをインストールします。
$ npm i -D enzyme-adapter-react-16
enzyme-adapter-react-16用の型定義を追加
TypeScriptの場合、モジュールだけでは型が無いと警告されるので対応する型定義のモジュールを追加します。
$ npm i -D @types/enzyme-adapter-react-16
テストファイルに適用
先ほど追加したモジュールを、Counter.spec.tsx
で設定しているenzymeモジュールに追加します。
// Counter.spec.tsx import * as React from 'react'; import { Counter } from '../Counter'; // 設定を変更するために、configureを追加 import { shallow, configure } from 'enzyme'; // enzyme-adapter-react-16モジュールを読み込む import * as Adapter from 'enzyme-adapter-react-16'; import { CounterState } from '../module' import { ActionDispatcher } from '../Container' // enzyme用のモジュールをadapterオプションに設定する configure({ adapter: new Adapter() }) //...