0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

既存のReact+ReduxプロジェクトにJest+Enzymeを導入しようとして躓いた点

Last updated at Posted at 2020-01-09

はじめに

フロントエンドのリファクタリングに伴い、Jest+Enzymeを用いたテストを導入することになった。
既存のプロジェクトは、React+Reduxで書かれており、複雑なWebpackの設定をしていたため、導入する際に躓いた点(発生したエラーと解決方法)をまとめる。

エラー発生時のpackage.json

react: 16.4.1
react-dom: 16.4.1
redux: 3.6.0
react-redux: 5.0.6
@babel/core: 7.0.0
webpack: 3.10.0
webpack-dev-server: 2.11.1

Jest + Enzymeの導入

基本的な流れ

基本的には以下の公式ドキュメント

に従って導入していった。
その後、既存のコンポーネントに対して、簡単なテスト(子コンポーネントが存在するか確認するだけ)が通せるように変更を加えた。

ドキュメントで苦戦したところ

基本的に書かれている通りに行えば上手くいった。
ドキュメント通りにやらなかったのでエラーが出た。

  • TypeError:Cannot read property 'current' of undefined
  • Getting Startedの_スナップショットテスト_で発生したエラー。
  • [原因] reactとreact-domのバージョンを16.9以上(ドキュメントでは最新にすべきだと書いてある)に上げる必要があるらしい。
  • [解決策] reactとreact-domのバージョンを上げれば動いた。

  • typeerror helpers(...).ensure is not a function
  • Getting Startedの_モック、Enzyme および React 16 を使用したスナップショットテスト(Enzyme)_で発生したエラー。
  • [原因] @babel/coreのバージョンが低かった。
  • [解決策] @babel/coreのバージョンを上げれば動いた。

  • Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none.
  • 同じく、Getting Startedの_モック、Enzyme および React 16 を使用したスナップショットテスト(Enzyme)_で発生したエラー。
  • [原因] Enzymeを利用するには、Reactのバージョンに対応したアダプターをインストールする必要がある。
  • [解決策] 今回はReact16であるため、enzyme-adapter-react-16をインストールした。また、設定のためテストコードに以下を追記した。(参考: React v16でAirbnbのenzymeを使う時の覚書)
hogehoge.test.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });

既存のコンポーネントに対する簡単なテスト(子コンポーネントが存在するか確認するだけ)で躓いたところ

  • Cannot find module 'hogehoge' from 'fugafuga'
  • importあたりで躓いた。
  • [原因] Webpackでエイリアスを利用していて、その設定がJest側にないために失敗する。
  • [解決策] 以下のように、Jestの設定にWebpackのエイリアスと同じ設定をする必要がある。以下は「jest.config.js」を利用して設定を行う例だが、「package.json」に記載する方法もある。(参考:Using with webpack)
jest.config.js
module.exports = {
    moduleNameMapper: {
        // 「/src/components/**」に対し、「component」というエイリアスを設定する例
        "^component/(.*)": "<rootDir>/src/components/$1",
        // 「/src/containers/**」に対し、「container」というエイリアスを設定する例
        "^container/(.*)": "<rootDir>/src/containers/$1",
    },
};

npm install react-css-modules
jest.config.js
module.exports = {
    moduleNameMapper: {
        // 以下の行を追加(正規表現は適切なものに変える)
        "\\.(css|less|svg)$": "<rootDir>/node_modules/jest-css-modules",
    },

  • Store周りの設定でエラー
  • [原因] WebpackにStore周りの設定があり、その設定がJest側にないために失敗する。
  • [解決策] webpack.config.jsのpluginsに書かれていたDefinePluginの設定を、jest.config.jsのglobalsに転記した。

  • Invariant Violation: Could not find "store" in either the context or props of "Connect(Login)".
  • Reduxコンポーネントをテストする際に失敗する。
  • [原因] Jestのテストはアプリケーションから独立しており、storeは作成されないし、Reduxのセットアップもされないので、JestがReduxのstoreを探し出せずにエラーになる。
  • [解決策] 今回はインテグレーションテストを想定しているため、storeのモックを使ってテストを行う。redux-mock-storeをインストールし、テストコードに以下を追記。(参考: Reduxコンポーネントをユニットテストする方法
    )
hogehoge.test.js
import configureStore from 'redux-mock-store'
>
// create any initial state needed
const initialState = {}; 
// here it is possible to pass in any middleware if needed into //configureStore
const mockStore = configureStore();
let wrapper;
let store;
beforeEach(() => {
    //creates the store with any initial state or middleware needed  
    store = mockStore(initialState);
    wrapper = shallow(<Login store={store}/>);
})

(引用: Reduxコンポーネントをユニットテストする方法)


  • SyntaxError: Unexpected token import
    > import Storage from 'react-native-storage';
  • react-native-storageをincludeする際にエラーになる。
  • [原因] react-native-storageはES6で書かれているため、トランスパイルが必要になる。Jestのデフォルト設定では、「node_modules/」配下はトランスパイルの対象外になっているので、トランスパイルされずにエラーとなる。(今回はreact-native-storageだけだが、react-native関連のパッケージは同様のエラーが起きる。)
  • [解決策] jest.config.jsに以下を追記し、node_modulesはトランスパイルの対象から外したまま、react-native-storageだけ対象に入れるように、デフォルトの設定を上書きする。(参考: Testing React Native Apps)
jest.config.js
    transformIgnorePatterns: [
        'node_modules/(?!(react-native-storage)/)'
    ],

  • console.warn node_modules/react-native-storage/storage.js:28
    Data would be lost after reload cause there is no storageBackend specified!
  • ローカルストレージを設定する必要がある。
  • これはまだ手を付けてない。
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?