モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)
目次目次を開く/閉じる

AngularJS 単体テスト

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2015/07/30
最終更新最終更新
2018/10/07
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    車輪の再発明は無駄ではないというスタンスでスクラッチ開発しがち

    0
    ステッカーを贈るとは?

    AngularJS の単体テストに Node.js, Karma, Jasmine, PhantomJS を利用する場合の例をまとめます。

    インストール

    サーバサイド JavaScript 環境である Node.js およびそのパッケージマネージャ npm をインストールします。CentOS 6 の場合は epel を利用すると簡単です。

    $ sudo yum install epel-release
    $ sudo yum install nodejs
    $ sudo yum install npm
    

    テスト実行環境 Karma パッケージをシステムインストールします。

    $ sudo npm install -g karma
    

    Karma 上で動作するテストフレームワーク Jasmine をシステムインストールします。

    $ sudo npm install -g karma-jasmine
    

    Jasmine 自体はブラウザをエミュレートできないため、テスト用のブラウザプラグインをシステムインストールします。PhantomJS は CUI で動作する画面出力のないブラウザです。例えば今回のようなテスト目的で使用されます。以下のコマンドで PhantomJS およびその Karma プラグインがインストールされます。

    $ sudo npm install -g karma-phantomjs-launcher
    

    この時点で karma コマンドが使用できない場合は別途以下のコマンドでインストールします。

    $ which karma  ←見つからないならば↓
    $ sudo npm install -g karma-cli
    

    動作検証

    初期設定ファイルを生成します。候補はタブで切り替え選択します。

    $ karma init
    

    質問への回答例

    Which testing framework do you want to use ?
    Press tab to list possible options. Enter to move to the next question.
    > jasmine
    
    Do you want to use Require.js ?
    This will add Require.js plugin.
    Press tab to list possible options. Enter to move to the next question.
    > no
    
    Do you want to capture any browsers automatically ?
    Press tab to list possible options. Enter empty string to move to the next question.
    > PhantomJS
    > 
    
    What is the location of your source and test files ?
    You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
    Enter empty string to move to the next question.
    > angular.js  ← minifyされていないもの
    30 07 2015 00:40:10.818:WARN [init]: There is no file matching this pattern.
    
    > angular-mocks.js  ← minifyされたものは提供されていない
    30 07 2015 00:40:19.179:WARN [init]: There is no file matching this pattern.
    
    > *_spec.js
    30 07 2015 00:40:26.764:WARN [init]: There is no file matching this pattern.
    
    > 
    
    Should any of the files included by the previous patterns be excluded ?
    You can use glob patterns, eg. "**/*.swp".
    Enter empty string to move to the next question.
    > 
    
    Do you want Karma to watch all the files and run the tests on change ?
    Press tab to list possible options.
    > yes
    
    Config file generated at "/vagrant/karma.conf.js".
    

    以下のテストコードを用意します。Jasmine の記法で記述します。

    sample_spec.js

    describe('テスト内容', function(){
      it('加算試験', function(){
        expect(1+2).toEqual(3);
      });
    });
    

    テストの開始

    $ karma start karma.conf.js
    

    無限ループで待機し続けます。ファイル編集を検知すると即時テストが実行されます。

    Jasmine 記法

    describe('Jasmine の使い方', function(){
      it('同一オブジェクトである', function(){
        var obj = {};
        var obj_ = obj;
        expect(obj_).toBe(obj);
        expect({}).not.toBe(obj);
      });
    
      it('値が等しい', function(){
        var obj = {};
        expect({}).toEqual(obj);
      });
    
      it('正規表現にマッチ', function(){
        expect('abc').toMatch('^[a-z]+$');
      });
    
      it('真偽値', function(){
        expect(true).toBeTruthy();
        expect(false).toBeFalsy();
      });
    
      it('値を含むかどうか', function(){
        expect([1,2,3]).toContain(1);
      });
    
      it('値の大小', function(){
        expect(1).toBeGreaterThan(0);
        expect(-1).toBeLessThan(0);
      });
    
      it('値が近い', function(){
        expect(0.001).toBeCloseTo(0);
      });
    
      it('例外を投げること', function(){
        var myfunc = function(){
          myUndefinedVar;
        };
        expect(myfunc).toThrow();
      });
    
      it('undefined であるかどうか', function(){
        expect(undefined).toBeUndefined();
      });
    
      it('null であるかどうか', function(){
        expect(null).toBeNull();
      });
    
      it('NaN であるかどうか', function(){
        expect(parseInt("str")).toBeNaN();
      });
    
    });
    

    AngularJS のテスト方法

    angular.js および angular-mock.js をダウンロードしておきます。

    sample_spec.js

    var app = angular.module('myApp', []);
    
    // フィルターの自作
    app.filter('myfilter', function(){
      return function(value){
        return angular.isNumber(value);
      };
    });
    
    // テストコード
    describe('カスタムフィルターのテスト例', function(){
      beforeEach(module('myApp'));
    
      it('myfilter 動作確認', inject(function($filter){
        var myfilter = $filter('myfilter');
        expect(myfilter(1)).toEqual(true);
        expect(myfilter('abc')).toEqual(false);
      }));
    });
    

    強制的にタイムアウトさせる必要があるサービスをテストする場合は $timeout のモックを利用します。

    var app = angular.module('myApp', []);
    
    app.service('mytimer', ['$timeout', function($timeout){
      this.prop = 'ABC';
      var self = this;
      $timeout(function(){
        self.prop = 'XYZ';
      }, 1000000); //msec
    }]);
    
    describe('$timeout を利用したカスタムサービスのテスト例', function(){
      beforeEach(module('myApp'));
    
      it('mytimer 動作確認', inject(function($timeout, mytimer){
        expect(mytimer.prop).toEqual('ABC');
        $timeout.flush();
        expect(mytimer.prop).toEqual('XYZ');
      }));
    });
    

    HTTP 通信を行うサービスをテストする場合は $httpBackend のモックを利用します。

    var app = angular.module('myApp', []);
    
    app.factory('myhttp', ['$http', function($http){
      return function(path){
        return $http.get(path);
      }
    }]);
    
    describe('$http を利用したカスタムサービスのテスト例', function(){
      beforeEach(module('myApp'));
    
      var httpBackend;
      beforeEach(inject(function($httpBackend){
        httpBackend = $httpBackend;
      }));
    
      it('myhttp 動作確認', inject(function(myhttp){
    
        httpBackend.expect('GET', '/api/mock').respond([
          {itemId: 0, value: 'a'},
          {itemId: 1, value: 'b'},
        ]);
    
        var promise = myhttp('/api/mock');
        var response;
        promise
          .success(function(data){
            response = data;
          })
          .error(function(data){
            response = data;
          });
    
        expect(response).toBeUndefined();
        httpBackend.flush();
        expect(response.length).toEqual(2);
    
      }));
    });
    
    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    車輪の再発明は無駄ではないというスタンスでスクラッチ開発しがち

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      関連記事

      • AngularJS 公式ドキュメントの利用例
        AngularJS はクライアントサイドの JavaScript フレームワークです。Angular は「角のある」という意味の英単語であり HTML のブラケットを表現しています。また随所で見られる ng というワードは発音が angular と似ているため採用されました。AngularJS の使用方法については様々な個人ブログにまとめられてはいますが、やはり公式ドキュメントが一番よくまとまって...
      • ルーティングを定義してシンプルな SPA を構築 (AngularJS)
        AngularJS は SPA (single page application) の構築をサポートしています。SPA を強制している訳ではないことに注意します。例えば SPA を構築する際に有用なモジュール ngRoute は外部モジュールとして提供されています。別途読み込みが必要です。 サンプルコード index.html <!DOCTYPE html> <html lang...
        カラフカラフ11/27/2017に更新
        いいねアイコン画像0
      • DOM 操作ディレクティブ (AngularJS)
        AngularJS のビルトインディレクティブのうち DOM 操作に関するものを、コード例とともに列挙します。公式ドキュメントはこちらです。 DOM 操作ディレクティブ <!DOCTYPE html> <html lang="ja" ng-app> <head> <meta charset="utf-8"> <script type="...
      • フィルター (AngularJS)
        AngularJS にはモデルの値を表示用に変換するフィルタという機能があります。コマンドラインにおけるパイプのように使用します。公式ドキュメントはこちらです。 フィルターの使用例 <!DOCTYPE html> <html lang="ja" ng-app="myApp"> <head> <meta charset="utf-8"> <...
      • HTTP 通信 (AngularJS)
        AngularJS における HTTP 通信では、XMLHttpRequest オブジェクトが利用されています。AngularJS で HTTP 通信を行うためのサンプルコードを以下に示します。公式ページはこちらです。 index.html <!DOCTYPE html> <html lang="ja" ng-app="myApp"> <head> <...