13

実行時にHTTPエンドポイントでいくつかの構成を実行するためにアプリが必要です。

私はそれを行うための簡単なサービスを書きました:

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をモックするためにこれを試しました:

beforeEach(inject(function($httpBackend) {

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

    angular.mock.module('app')

    $httpBackend.flush();
}));

しかし、得た:

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)

AngularJS1.0.6へのアップデート以降の編集

AngularチームのIgorのアドバイスを受けてAngularJS1.0.6にアップデートしたので、問題はなくなりましたが、今ではこれがあります。これはより「正常」に聞こえますが、作成方法がわかりません。できます。

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

3 に答える 3

16

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

私が達成したかったのは、サービスを正常にスタブし、応答を強制することです。コントローラーでは$httpBackend、コントローラーを開始する前に、要求スタブまたは例外で使用することができました。app.run()ロードすると、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()これが将来のテストに役立つことを願っています。

于 2013-04-17T16:52:56.610 に答える
5

あなたがまだこの質問に対する答えを探しているかどうかはわかりません。しかし、ここに役立つかもしれないいくつかの情報があります。

$ injectorは、モジュールではなく、アプリケーションのシングルトンです。ただし、angular.injectorは、実際にはモジュールごとに新しいインジェクターを作成しようとします(

beforeEach(module("app")); 

最初に。

Angular、RequireJS、Karma、Jasmineを使用しているときに同じ問題が発生し、それを解決する2つの方法を見つけました。テストでは、個別の依存関係としてインジェクター関数のプロバイダーを作成しました。たとえば、$injectorのシングルトンインスタンスを提供するMyInjectorProvider。

もう1つの方法は、次のステートメントを移動することでした。

beforeEach(module("app"));
beforeEach(inject(function($injector){
    ...
})

テストスイートの説明内。これが以前の様子です:

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(){...});
    });
});

修正を適用すると、次のようになります。

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(){...});
    });
});

私の場合、両方のソリューションが機能しました。

于 2013-11-05T01:58:22.883 に答える
1

ngMock。$httpBackendを使用してすべてのHTTPリクエストをモックする必要があります。また、ここにガイドがあります


アップデート

あなたはそれを必要とせずangular.mock.module、ただあなたのアプリモジュールを注入する必要があります。このようなもの:

var httpBackend;

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

テストでは、モックされたhttpに応答する必要がある場合は、を呼び出しますhttpBackend.flush()。これが、私たちがそれへの参照を持っている理由です。したがって、あなたが持っているすべてのテストでそれを注入する必要はありません。

動作させるには、angular-mock.jsをロードする必要があることに注意してください。

于 2013-03-26T18:10:34.103 に答える