使用AngularJS在app运行时加载内容时的单元测试

arn*_*ton 13 javascript angularjs

我需要我的应用程序在运行时通过HTTP端点运行一些配置.

我写了一个简单的服务来做到这一点:

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

接下来,我在我的app模块的运行块中调用此模块:

angular.module('app').***.run(function(config) {
        config.load();
    });
Run Code Online (Sandbox Code Playgroud)

应用程序运行时一切正常,但在我的单元测试中,我收到此错误:"错误:意外请求:GET/config"

我知道它意味着什么,但我不知道如何从运行块发生它时嘲笑它.

谢谢你的帮助

编辑添加规格

在每个之前调用它

beforeEach(angular.mock.module('app'));
Run Code Online (Sandbox Code Playgroud)

试过这个来模拟$ httpBackend:

beforeEach(inject(function($httpBackend) {

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

    angular.mock.module('app')

    $httpBackend.flush();
}));
Run Code Online (Sandbox Code Playgroud)

但得到了:

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)
Run Code Online (Sandbox Code Playgroud)

自更新到AngularJS 1.0.6后编辑

由于我已经更新到AngularJS 1.0.6,由Angular团队的Igor建议,问题已经消失,但现在我已经有了这个,听起来更"正常",但我仍然无法弄清楚如何制作有用.

Error: Injector already created, can not register a module!
Run Code Online (Sandbox Code Playgroud)

hal*_*ube 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');
    });

});
Run Code Online (Sandbox Code Playgroud)

我希望这有助于您app.run()将来的测试.


drc*_*coa 5

我不知道你是否还在寻找这个问题的答案.但这里有一些可能有用的信息.

$ injector是应用程序的单例,而不是模块.但是,angular.injector实际上会尝试为每个模块创建一个新的注入器(我想你有一个

beforeEach(module("app")); 
Run Code Online (Sandbox Code Playgroud)

在开始.

我在使用Angular,RequireJS,Karma和Jasmine时遇到了同样的问题,我想出了两种方法来解决它.我在我的测试中为注入器函数创建了一个独立的依赖项.例如MyInjectorProvider,它提供$ injector的单例实例.

另一种方法是移动以下语句:

beforeEach(module("app"));
beforeEach(inject(function($injector){
    ...
})
Run Code Online (Sandbox Code Playgroud)

在测试套件描述中.所以这是它以前的样子:

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(){...});
    });
});
Run Code Online (Sandbox Code Playgroud)

应用修复后,它看起来像这样:

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(){...});
    });
});
Run Code Online (Sandbox Code Playgroud)

这两种解决方案都适用于我的情况.