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

AngularJS TIPS

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

2016年8月25日

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

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

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

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

 テスト対象のコードには、別稿3「TIPS:アプリ内でよく利用するビジネスロジックを定義するには?(serviceメソッド)」で紹介したAreaServiceサービスを採用します。本稿で説明するテスト用に、/angular_tips/UnitTest/scriptsフォルダー内にservice.jsファイルを新規作成し、別稿3のservice.jsファイルとして示しているJavaScriptコードをそのままコピーしてください。具体的にはリスト1のようになります(コードの詳細は別稿3を参照してください)。なお、今回のサンプルコードではモジュール名を「myAppService」から「myApp.service」に変更しているので注意してください。

JavaScript
angular.module('myApp.service', [])
  .service('AreaService', ['$log', function($log) {
    this.square = function(base, height) {
      $log.debug('[四角形]' + base + '×' + height);
      return base * height;
    };

    this.circle = function(radius) {
      $log.debug('[円(半径)]' + radius);
      return radius * radius * Math.PI;
    };

    this.diamond = function(diagonal1, diagonal2) {
      $log.debug('[ひし形]' + diagonal1 + '×' + diagonal2);
      return diagonal1 * diagonal2 / 2;
    };
  }]);
リスト1 テスト対象となるAreaServiceサービスのコード(/angular_tips/UnitTest/scripts/service.js)
(2)テストスクリプトを準備する

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

JavaScript
describe('AreaServiceサービスのテスト', function() {
  var AreaService;

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

  beforeEach(inject(function(_AreaService_){
    AreaService = _AreaService_;
  }));

  it('四角形の面積を求める', function() {
    expect(AreaService.square(3, 2)).toEqual(6);
  });

  it('円の面積を求める', function() {
    expect(AreaService.circle(3)).toEqual(28.274333882308138);
  });

  it('ひし形の面積を求める', inject(function($log) {
    expect(AreaService.diamond(4, 9)).toEqual(18);
  }));
});
リスト2 AreaServiceサービスをテストするためのコード(/angular_tips/UnitTest/spec/service_spec.js)

 テストの構造は、別稿1でも示したものとほぼ同じなので、本稿では異なる点――太字の部分に絞って解説していきます。

 まず、テストスイートの中で共通して利用するサービスは、beforeEachメソッドで準備しておくべきです*1。この例のように、beforeEachメソッドは必要に応じて複数記述しても構いません。

  • *1 別稿2では$filterサービスを利用していましたが、このルールからすれば、今回のAreaServiceサービスと同様にbeforeEachメソッドで準備しておくべきでしょう。

 準備したサービスは個々のitメソッドから呼び出せる必要があるので、ブロック外部の変数AreaServiceに格納しておきます。この際、コードの可読性という観点から、大概、外部変数とサービスとは同名にしておきたいはずです。が、ここで注入時の変数と名前がバッティングしてしまうのは困りものです。

 そこでAngularJSでは「アンダースコアラッピング」という記法を用意しています。これは、サービスを注入する際に、サービス名をアンダースコア(_)でくくれるというルールです。注入に際しては、前後のアンダースコアを除去した名前で解釈しますので、この例であれば_AreaService_AreaServiceとは同じ意味になります。

 アンダースコアラッピング記法を利用することで、外部変数と注入時の変数との名前の衝突を避けられるようになりました。

 サービスを準備できてしまえば、あとは適当な引数を与えてサービスを実行し、その結果をあらかじめ用意した期待値と比較する、という流れは、別稿2で解説したもの(Jasmine標準の検証メソッドとitメソッドによる各テストケースの実装)と同様です。

(3)テストスイートを実行する

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

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

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

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

AngularJSで一般的に採用されているテスティングフレームワーク「Karma+Jasmin」による単体テスト環境を構築する手順を説明する。

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

サイトからのお知らせ

Twitterでつぶやこう!