この前書いた記事で AngularJS を使ったプログラムのテストを Karma で実行しました。今回は単純な filter のテストではなく directive のテストを書いていきます。

必要な知識

  • JavaScript
  • AngularJS
  • npm コマンド
  • bower コマンド
  • karma コマンド

準備

まずは必要なモジュールをインストールします。 HTML テンプレートに Jade を使うので karma-ng-jade2js-preprocessor をインストールしておきます。

$ npm install -g karma-cli
$ npm install karma karma-ng-jade2js-preprocessor
$ bower install assert angular angular-mocks

プログラムを書く

テストと、テストされるプログラムを書いていきます。まずはテストされる directive とそのテンプレートから。

angular.module('app', []).directive('superElement', function() {
    return {
        transclude: true,
        templateUrl: 'tmpl.html'
    };
});
div
  | Super 
  span(ng-transclude)

頭に Super とだけつけて表示する directive です。テンプレートは template.jade という名前をつけて保存します。

続いてテストケースを。

describe('super-element directive', function() {

    beforeEach(module('app', 'template.html'));

    it('should be div', inject(function($rootScope, $compile) {
        var factory = $compile('<div super-element>{{ content }}</div>');
        var scope = $rootScope.$new();
        scope.content = 'プリン';
        var element = factory(scope);
        scope.$digest();
        assert(element.text() === 'Super プリン');
    }));

});

肝は $compile です。これが HTML をコンパイルしてくれます。

scope.$digest() のタイミングで {{ content }}プリン に置き換えられるので、これも忘れてはいません。

element にはコンパイルされた DOM ノードが jQuery(Lite) でラップされた形で入っています。この element をあれこれしてテストしていけばOKです。今回は text() メソッドできちんと頭に Super という文字列が付いているか確認しています。

テストで読み込まれている template.html というモジュールは template.jade を元に karma-ng-jade2js-preprocessor が作ってくれるものです。モジュール名はファイル名から決まります。細かい設定に関しては karma-ng-jade2js-preprocessor のドキュメントを読めば書いてあります。

ちなみに、テンプレートを素の HTML で書いているなら karma-ng-html2js-preprocessor というプリプロセッサが使えます。

テストの実行

最初の実行の前に Karma の設定をします。

$ karma init # いろいろ聞かれるので答える

作られた karma.conf.js にテスト対象の情報や、 Jade の変換方法などを書き加えていきます。

    files: [
      'bower_components/angular/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'bower_components/assert/assert.js',
      '*.js',
      '*.jade'
    ],

    preprocessors: {
        '*.jade': 'ng-jade2js'
    },

filespreprocessors'*.jade' を書き加えればあとは適当に。

karma コマンドでテストを実行します。

$ karma start --single-run

テストが成功したはずです。試しにテンプレートを編集してわざと壊してみるとちゃんと失敗するはずです。

まとめ

  • $compile() で directive を使った HTML をコンパイルできる
  • $scope.digest() のタイミングで {{ ... }} が展開される
  • テンプレートを別ファイルにしていても、 karma-ng-**2js-preprocessor というプリプロセッサを使えばテストできる