2013-03-26 10 views
13

実行時にHTTPエンドポイントで設定を実行するにはアプリが必要です。AngularJSを使ってアプリケーションをロードするときのユニットテスト

私はそれを行うためのシンプルなサービスを書いた:

module.factory('config', function ($http, analytics) { 
    return { 
     load: function() { 
      $http.get('/config').then(function (response) { 
       analytics.setAccount(response.googleAnalyticsAccount); 
      }); 
     } 
    } 
}); 

次へ]を、私は私のアプリモジュールの実行ブロックにこのモジュールを呼び出す:

angular.module('app').***.run(function(config) { 
     config.load(); 
    }); 

アプリがあるときは、すべてがうまく機能しています"エラー:予期しない要求:GET/config"

私はそれが何を意味しているのか知っていますが、実行ブロックから起こったときにそれを模擬する方法がわかりません。あなたの助けのための

おかげ各

beforeEach(angular.mock.module('app')); 

は$ httpBackendを模擬するために、これをしようとしました前にこれを呼び出す仕様

を追加する

EDIT:

beforeEach(inject(function($httpBackend) { 

    $httpBackend.expectGET('/config').respond(200, {'googleAnalyticsAccount':}); 

    angular.mock.module('app') 

    $httpBackend.flush(); 
})); 

しかし得ました:

AngularJS私は角度チーム、問題がなくなっているからイゴールにより、AngularJS 1.0.6にアップデートをお勧めしてきたので1.0.6

への更新からは

TypeError: Cannot read property 'stack' of null 
     at workFn (/Users/arnaud/workspace/unishared-dredit/test/lib/angular/angular-mocks.js:1756:55) 
    TypeError: Cannot read property 'stack' of null 
     at workFn (/Users/arnaud/workspace/unishared-dredit/test/lib/angular/angular-mocks.js:1756:55) 
    TypeError: Cannot read property 'stack' of null 
     at workFn (/Users/arnaud/workspace/unishared-dredit/test/lib/angular/angular-mocks.js:1756:55) 

EDITが、今私は今持っていますこれは、より "正常"と聞こえるが、私はまだそれを動作させる方法を理解できない。

Error: Injector already created, can not register a module! 
+2

'run()'をテストするときにもこのエラーが発生します – halfcube

+0

私は最終的にアプリケーションルートコントローラでテスト可能にするために移動しました。 –

答えて

16

私はこのエラーでしばらくの間苦労しましたが、賢明な解決策を思いつきました。

私が達成したいのは、サービスを正常にスタブし、応答を強制することです。コントローラーを起動する前に、要求スタブまたは例外で$httpBackendを使用することが可能でした。 には、moduleをロードするとオブジェクトが初期化され、サービスなどに接続されます。

次の例を使用してサービスをスタブすることができました。

describe('Testing App Run', function() { 
    beforeEach(module('plunker', function ($provide) { 
     return $provide.decorator('config', function() { 
      return { 
       load: function() { 
        return {}; 
       } 
      }; 
     }); 
    })); 


    var $rootScope; 
    beforeEach(inject(function (_$rootScope_) { 
     return $rootScope = _$rootScope_; 
    })); 

    it("defines a value I previously could not test", function() { 
     return expect($rootScope.value).toEqual('testing'); 
    }); 

}); 

私はこれが今後あなたのapp.run()試験に役立つことを願っています。

+0

'config'デコレータはangleのconfigステージを参照していませんが、ファクトリサービスOPには 'config'という名前が付いています。 – ErikAGriffin

+0

これはAngular 1.0.5の時間を中心に書かれています。 – halfcube

1

すべてのHTTPリクエストをngMock.$httpBackendでモックする必要があります。また、here is a guide


更新

あなたは自分のアプリのモジュールを挿入する必要があり、angular.mock.module事を必要としません。このような何か:あなたのテストでは

var httpBackend; 

beforeEach(module('app')); 
beforeEach(inject(function($httpBackend) { 
    httpBackend = $httpBackend; 
    $httpBackend.expectGET('/config').respond(200, {'googleAnalyticsAccount': 'something'}); 
})); 

、あなたが答えるために嘲笑HTTPを必要とするとき、あなたはhttpBackend.flush()を呼び出します。これが私たちが参照する理由です。あなたが持っている1回のテストでそれを注入する必要はありません。

angle-mock.jsを読み込む必要があります。

+0

あなたの答えをありがとう。 angular.mock.moduleを呼び出す前に注入を行うと、Injectorがすでに作成されているというエラーが表示されます –

+0

関連する仕様を投稿してください。 –

+0

あなたの助けを借りて、ちょうど投稿されました! –

5

まだこの質問に対する回答を探しているかどうかわかりません。しかしここに役立つ情報があります。

$ injectorは、アプリケーション用でモジュール用ではないシングルトンです。しかし、angular.injector実際には(私はあなたが先頭に

beforeEach(module("app")); 

があるとし、各モジュールのための新しいインジェクターを作成しようとします。

角度、RequireJSを使用している間、私は同じ問題を抱えていた、カルマとジャスミンと私はそれを解決するための2つの方法を考え出しました。私はインジェクタ関数のプロバイダを、私のテストで別個の依存関係として作成しました。例えば、$ injectorのシングルトンインスタンスを提供するMyInjectorProvider

もう1つの方法は、次の文:

テストスイートの説明の中に
beforeEach(module("app")); 
beforeEach(inject(function($injector){ 
    ... 
}) 

があります。

define(['services/SignupFormValidator'], function(validator){ 
    var validator; 

    describe("Signup Validation Tests", function(){ 
     beforeEach(module("app")); 
     beforeEach(inject(function($injector){ 
      validator = $injector.get("SignupFormValidator"); 
     }); 

     it("...", function(){...}); 
    }); 
}); 

どちらのソリューションは、私の場合で働いていた:それはこのようになります修正を適用すると

define(['services/SignupFormValidator'], function(validator){ 
    var validator; 
    beforeEach(module("app")); 
    beforeEach(inject(function($injector){ 
     validator = $injector.get("SignupFormValidator"); 
    }) 

    describe("Signup Validation Tests", function(){ 
     it("...", function(){...}); 
    }); 
}); 

:だから、ここでそれが前に見えた方法です。

関連する問題