Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
AngularJS TIPS

AngularJS TIPS

AngularJSのコントローラーを単体テストするには?

2016年8月29日

テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「コントローラー」の単体テストを記述し、それを実行する方法を解説する。

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

 別稿1「TIPS: AngularJSアプリの単体テストを実施するには?(準備編)」+別稿2「同(実行編)」では、KarmaJasmine環境でAngularJSアプリをテストする基本的な手順について解説しました。本稿では、引き続いてKarma+JasmineでAngularJSのコントローラーをテストする方法について解説します。

(1)テスト対象のコード

 テスト対象のコードには、別稿3「TIPS:イベントリスナーを登録するには?」で紹介したmyControllerコントローラーを採用します。別稿3ではevent.htmlファイルを作成していますが、本稿で説明するテスト用に、/angular_tips/UnitTest/scriptsフォルダー内にcontroller.jsファイルを新規作成し、別稿3のevent.htmlファイルで示しているJavaScriptコード部分のみをcontroller.jsファイルにコピーしてください。具体的にはリスト1のようになります(コードの詳細は別稿3を参照してください)。なお、今回のサンプルコードではモジュール名を「myApp」から「myApp.controller」に変更しているので注意してください。

JavaScript
// myApp.controllerモジュールにmyControllerコントローラーを登録
angular.module('myApp.controller', [])
  .controller('myController', ['$scope', function($scope) {
    // 変数msgを初期化
    $scope.msg = 'こんにちは、誰かさん!';
    // clickイベントリスナーを設定
    $scope.onclick = function() {
      $scope.msg = 'こんにちは、' + $scope.name + 'さん!';
    };
  }]);
リスト1 テスト対象となるmyControllerコントローラーのコード(/angular_tips/UnitTest/scripts/controller.js)
(2)テストスクリプトを準備する

 まずは、テストのためのコードを準備します。その基本的な方法は、別稿2で説明しています。今回はリスト2のテストコードを記述しました。

JavaScript
describe('MyControllerコントローラーのテスト', function() {
  var scope;

  beforeEach(module('myApp.controller'));

  beforeEach(inject(function(_$rootScope_, _$controller_){
    var $rootScope = _$rootScope_;
    var $controller = _$controller_;
    scope = $rootScope.$new();
    // 1第2引数に$scopeを渡す
    $controller('myController', { $scope: scope });
  }));

  it('スコープのチェック', function() {
    expect(scope.msg).toEqual('こんにちは、誰かさん!');
    scope.name = '山田太郎';
    scope.onclick();
    expect(scope.msg).toEqual('こんにちは、山田太郎さん!');
  });
});
リスト2 コントローラーをテストするためのコード(/angular_tips/UnitTest/spec/controller_spec.js)

 2つ目のbeforeEachメソッド内のコードについて説明します。

 コントローラーをテストするには、まず$controllerサービスでコントローラーをインスタンス化します。

[構文]$controllerサービス

$controller(name, locals)

  • name: コントローラー名
  • locals: コントローラーに注入する値(「引数名: 値」のハッシュ形式)

 コントローラーには$scopeを渡しますので、この例でも{ $scope: scope }として第2引数localsに渡しています(1)。$scopeオブジェクトは、$rootScopeサービスの$newメソッドで生成できます。$rootScopeサービスは、アプリ唯一のルートとなるスコープです。

 $newメソッドの引数には、新規のスコープが$rootScopeから独立しているかどうかをブール値で指定します。一般的に、コントローラーに渡す$scopeオブジェクトは$rootScopeを継承しているはずなので、引数にはfalseを指定しておきます。デフォルトはfalseなので、空でも構いません。

 $controllerサービスは、戻り値としてコントローラーのインスタンスを返しますが、テストでは利用していません。初期化された$scopeオブジェクトだけを変数scopeに格納しておきましょう。

 これでコントローラーをテストするための準備ができました。あとはitメソッドによる各テストケースの実装で、Jasmine標準の検証メソッドを使って、以下の内容を確認しておきましょう。

  • 初期状態でmsgプロパティの値が「こんにちは、誰かさん!」であること
  • nameプロパティに「山田太郎」を設定した後、onclickメソッドを呼び出すことで、msgプロパティの内容が「こんにちは、山田太郎さん!」になること
(3)テストスイートを実行する

 テスト実行の手順は、別稿2を参照してください。

処理対象:テスト カテゴリ:基本
処理対象:Karma+Jasmine カテゴリ:基本
処理対象:コントローラー(Controllers) カテゴリ:基本
API:angular.module カテゴリ:ng(コアモジュール) > function(関数)
API:$injector カテゴリ:auto > service(サービス)
API:$controller カテゴリ:ngMock > service(サービス)
API:$rootScope カテゴリ:ng > service(サービス)
API:$rootScope.Scope カテゴリ:ng > type(型)

※以下では、本稿の前後を合わせて5回分(第69回~第73回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

AngularJS TIPS
69. AngularJSアプリの単体テストを実施するには?(実行編)

テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSアプリの単体テストを記述して、それをテスト実行するまでの手順を説明する。

AngularJS TIPS
70. AngularJSのサービスを単体テストするには?

テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「サービス」の単体テストを記述し、それを実行する方法を解説する。

AngularJS TIPS
71. 【現在、表示中】≫ AngularJSのコントローラーを単体テストするには?

テスティングフレームワーク「Karma+Jasmin」を使って、AngularJSの「コントローラー」の単体テストを記述し、それを実行する方法を解説する。

AngularJS TIPS
72. ディレクティブを自作するには?(directiveメソッド)

AngularJSで、ビューの操作/生成を独立させて独自ディレクティブを作成する基本的な定義方法と使用例を説明する。

AngularJS TIPS
73. ディレクティブで利用するテンプレートを外部ファイル化するには?(templateUrlプロパティ)

ビューの操作/生成を定義した自作ディレクティブのテンプレートを外部ファイル化して利用する方法を解説。また、ビューの中で<script>要素としてテンプレートを宣言する方法も説明する。

サイトからのお知らせ

Twitterでつぶやこう!