SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Webアプリケーション開発技術の新潮流スタディーズ

いま最も注目のライブラリ「React.js」でシングルページアプリケーションを作ってみよう! 【後編】

Webアプリ開発技術の新潮流スタディーズ 第2回


  • X ポスト
  • このエントリーをはてなブックマークに追加

Tips 2:React.addons.TestUtils+Jestでユニットテストを作成する

 ここでテストについても触れておきましょう。

 React.jsは、コンポーネントのテストに特化したユーティリティをアドオンとして提供しています(公式ドキュメントを参照)。テストフレームワークには何を使ってもよいのですが、公式ドキュメントでFacebook製の「Jest」が紹介されているので、簡単に紹介します。

Jestとは

 Jestは、BDD(振る舞い駆動開発)テストフレームワークとして人気の「Jasmine」を拡張したライブラリで、依存するすべてのモジュールを自動的にモックするのが大きな特徴です。これによって、確実にテスト対象だけをテストすることができます。

Note

 本稿執筆時点(2015年3月2日)で、Jestは最新バージョンのNode.js(v0.12.0)で動作しません。Jestの代わりにMochaを使う場合は、後述のTips 3を参考にしてください。

Jestのインストールと準備

 まず、npmを使ってJestをインストールします。

$ npm install jest-cli --save-dev

 次に、Reactのアプリケーションでテストを行うために、次の準備を行います。

  • reactモジュールを自動モック化の対象から外す(必須)
  • プリプロセッサによって、事前にJSXをJavaScriptにコンパイルする(JSX使用時は必須)
  • テストを配置するディレクトリ名を「test」に変更する(任意。デフォルトは__tests__
  • npm testコマンドでテストを実行できるようにscriptsに追記する(任意)

 各設定はpackage.json内で管理します。"scriptPreprocessor"で指定されているpre-test.jsが、JSXをJavaScriptにコンパイルするプリプロセッサです。

package.json
  "scripts": {
    "test": "jest",
  
    ...
  
  },
  
  ...

  "jest": {
    "testDirectoryName": "test",
    "scriptPreprocessor": "<rootDir>/pre-test.js",
    "unmockedModulePathPatterns": [
      "react",
      "object-assign"
    ]
  }
pre-test.js
var ReactTools = require('react-tools');
module.exports = {
  process: function(src) {
    return ReactTools.transform(src);
  }
};
Note

 Windows環境にJestを導入する場合、いくつか乗り越えるべき障害があるかもしれません。筆者はこちらを参考にしました。

 また、モック化によって特定のモジュールが壊れるバグが報告されています。例ではobject-assignをモック対象から外して回避しています。

テストを書く

 せっかくのBDDライブラリですので、テスト駆動で書くためにTODOアプリに次の仕様を追加します。

  • TodoStorage.createのコールバック関数がエラーオブジェクトを返した場合には、入力欄を空欄にしない

 テストの都合上、<TodoForm>コンポーネントをtodo-form.jsに切り出しました。続いて、todo-form-test.jsに次のようにテストを記述します[7]

test/todo-form-test.js
// テスト対象のモジュールをモック対象から外す
jest.dontMock('../src/todo-form.js');

describe('todo-form', function() {
    it('should keep input value when submission fails', function() {
        var React = require('react/addons');
        var TodoForm = require('../src/todo-form.js');
        var TestUtils = React.addons.TestUtils;

        var form = TestUtils.renderIntoDocument(<TodoForm/>);

        // 入力が'ok'でない場合にエラーを返すように、TodoStorageのモックオブジェクトを作成
        var TodoStorage = require('../src/storage.js');
        TodoStorage.create.mockImplementation(function(name, callback) {
            callback(name === 'ok' ? null : 'error');
        });

        var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'input')[0];
        var button = TestUtils.scryRenderedDOMComponentsWithTag(form, 'input')[1];

        // 1: inputが'ok'の状態でsubmitすると、inputが初期化される
        TestUtils.Simulate.change(input, { target: { value: 'ok' }});
        TestUtils.Simulate.submit(button);

        expect(TodoStorage.create).toBeCalled();
        expect(input.getDOMNode().value).toBe('');

        // 2: inputが'ng'の状態でsubmitすると、inputは初期化されずに残る
        TestUtils.Simulate.change(input, { target: { value: 'ng' }});
        TestUtils.Simulate.submit(button);

        expect(TodoStorage.create).toBeCalled();
        expect(input.getDOMNode().value).toBe('ng');
    });
});

 コードからは、React.addons.TestUtilsによって、DOMのイベントをシミュレートできていることが分かると思います。

[7] アサーションの書き方はJasmineのドキュメントを参照してください。

テストを通す

 npm testコマンドでテストが失敗しているのを確認したら、テストが通るように実装を追加します。

todo-form.js
  handleSubmit: function(e) {
    e.preventDefault();
    var name = this.state.name.trim();
    TodoStorage.create(name, function(error) {
+     if(!error) {
        this.setState({
          name: ''
        });
+     }
    }.bind(this));
  },

次のページ
Tips 3:React.addons.TestUtils+Mochaでユニットテストを作成する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Webアプリケーション開発技術の新潮流スタディーズ連載記事一覧

もっと読む

この記事の著者

鳥居 陽介(株式会社ワークスアプリケーションズ)(トリイ ヨウスケ)

株式会社ワークスアプリケーションズ所属。イケてるアプリケーションを死ぬほど楽に作るために研究を続ける日々。社内での立ち位置は「フロントエンドのナウい人」。最近エバンジェリストという肩書きが付いた。趣味は作曲とスノーボード。 Blog: http://jinjor-labo.hatenablog.com/ ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8512 2015/04/24 16:54

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング