SHOEISHA iD

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

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

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

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

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


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

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

 Jestの代わりに「Mocha」を使う場合は、こちらの説明を参考にしてください。同じことを行うため、Tips 2と説明が重複しますがご容赦ください。

Mochaのインストールと準備

 Mochaはテストライブラリとアサーションライブラリが独立していることが特徴のフレームワークで、自分の好きな組み合わせでテストを行うことができます。また、ブラウザ上のテストだけでなく、コマンドからNode.jsモジュールをテストすることもできます[8]

 ここでは、アサーションライブラリとして「should」、モックライブラリとして「Sinon」を使うことにします。

 それから、通常Node.jsではブラウザテストができないため、DOMをシミュレートするために「jsdom」を使います。また、require(...)をモックするために「proxyquire」を使います。

 さらに、MochaではJSXを直接読むことができないため、事前にreact-tools(jsxコマンド)を使ってコンパイルします。

事前にJavaScriptへのコンパイルが必要
事前にJavaScriptへのコンパイルが必要

 

 まず、上記で挙げた必要なものをすべてインストールします。

$ npm install mocha should sinon jsdom react-tools proxyquire --save-dev

 次に、npmから実行できるように、package.jsonの"scripts"に記述します。

package.json
  "scripts": {
    "pretest": "jsx src/ compiled-js/src/ & jsx test/ compiled-js/test/",
    "test": "mocha compiled-js/test --harmony",
  
    ...
  
  },
Note

 コマンド名に接頭辞prepostを付けたコマンド(例えば"test"に対して"pretest""posttest")は、そのコマンドの実行前、実行後にそれぞれ実行されます。

[8] Mochaの詳しい使い方については、CodeZineの過去記事に説明があります、こちらを参照してください。

テストを書く

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

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

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

test/todo-form-test.js
// ブラウザのグローバル変数をNode.js上で使うための準備
var jsdom = require('jsdom').jsdom;
global.document = jsdom('<html><body></body></html>');
global.window = document.defaultView;
global.navigator = window.navigator;

var should = require('should');
var sinon = require('sinon');
var proxyquire = require('proxyquire');

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

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

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

        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);

        TodoStorageSpy.withArgs('ok').callCount.should.equal(1);
        input.getDOMNode().value.should.equal('');

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

        TodoStorageSpy.withArgs('ng').callCount.should.equal(1);
        input.getDOMNode().value.should.equal('ng');
    });
});

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

テストを通す

 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));
  },

まとめ

 以上、全2回にわたってReact.jsでのアプリケーション開発について駆け足で紹介してきました。ここで紹介した以外にも、アニメーションやサーバサイドレンダリングなど、高度なトピックはまだまだあります。必要に応じてキャッチアップするとよいでしょう。

 今回はシングルページアプリケーションを丸ごとReact.jsで構築しましたが、実際には、最初から新規プロダクトの構築に着手する機会は多くないかもしれません。React.jsは他のフレームワークと比べて柔軟にライブラリを組み合わせて使えるように設計されているため、途中から導入することも可能でしょう(弊社でもいくつかのプロジェクトで一部に採用しています)。

 最近になり、日本語でのReact.js紹介記事が増えており、導入の敷居が下がっています。この機会に選択肢の1つとして検討されてみてはいかがでしょうか。

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

  • 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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー

アクセスランキング

アクセスランキング