LoginSignup
11
12

More than 5 years have passed since last update.

React / flux の store のテスト

Last updated at Posted at 2015-10-21

概要

  • flux の store 部分のテストの書き方。
  • jest を使う。
  • 入力は Action。結果は Store の状態と Change Listener が呼ばれることを確認。
  • localStorage のモック。

テスト対象

web/static/js/stores/AuthStore.js をテストします。
以下の機能を持っています。

  • LOG_IN アクションを受け取ると token を localStorage に保存し、Change Listener に通知する。
  • LOG_OUT アクションを受け取ると token を localStorage から削除し、Change Listener に通知する。

環境設定

elixir / phoenix の勉強用に作成したサンプル (tag qiita-jest-flux-store)を使って説明します。

jest-cli, react-addons-test-utils をインストールします。(npm に jest というパッケージもありますが別のものです。)

npm install jest-cli --save-dev
npm install react-addons-test-utils --save-dev

React 用に package.json に設定を書きます。
JSX / ES6 の変換、react 関連のモジュールのモック化の除外設定をしています。

package.json
"jest": {
    "rootDir": "./web/static/js",
    "scriptPreprocessor": "../../../node_modules/babel-jest",
    "unmockedModulePathPatterns": [
      "react",
      "../../../node_modules/react",
      "../../../node_modules/react-dom",
      "../../../node_modules/react-addons-test-utils"
    ]
  }

テスト作成

jest は __tests__ ディレクトリにあるテストを実行するので、__tests__ ディレクトリを作成します。

mkdir web/static/js/stores/__tests__

AuthStore-test.js を作成し、モックの設定をします。
jest はデフォルトで全てのモジュールをモック化するので、基本的には モック化しないモジュール のみ設定します。

AuthStore-test.js
jest.mock('../../dispatcher/AppDispatcher');
jest.dontMock('../../constants/Constants');
jest.dontMock('../AuthStore');

AuthStore はテスト対象なので除外します。
Constatnts は入力用のアクションが定義されているため除外します。
AppDispatcher はモック化されるはずですが、なぜかモックにならなかったため、モックにするように設定しています。

jest の実行環境では localStorage がないため、localStorage のモックも作成します。

AuthStore-test.js
var mock = (function() {
  var store = {};
  return {
    getItem: function(key) {
      return store[key];
    },
    setItem: function(key, value) {
      store[key] = value.toString();
    },
    clear: function() {
      store = {};
    }
  };
})();
Object.defineProperty(window, 'localStorage', { value: mock });

Store が AppDispatcher に登録したコールバックは、mock から取得します。

AuthStore-test.js
callback = AppDispatcher.register.mock.calls[0][0];

このコールバックに Action を送ることで、Store の dispatcher を実行できます。

AuthStore-test.js
  var actionLogIn = {
    type: ActionTypes.LOG_IN,
    token: 'abc'
  };
  callback(actionLogIn);

store から Change Listener 通知を確認するため、リスナーを作成し登録します。テスト実行後はリスナーを削除します。

AuthStore-test.js
    var calledOnChange = false;
    let onChange = () =>  calledOnChange = true;

    Store.addChangeListener(onChange);
    callback(actionLogIn);
    Store.removeChangeListener(onChange);

callOnChange はリスナーが呼ばれたことを確認するためのフラグです。

結果を確認します。

AuthStore-test.js
    expect(Store.isLoggedIn()).toBeTruthy(); // ログイン状態の確認
    expect(Store.getToken()).toBe('abc'); // トークンの確認
    expect(calledOnChange).toBeTruthy(); // Change Listener が呼ばれたことの確認

ログアウトや初期値のテストを含めたテスト全体はこちらを参照してください。

参考

11
12
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
11
12