为angularjs控制器测试注入模拟服务

Jos*_*mes 21 angularjs

我正在尝试测试依赖于我自己构建的服务的控制器.我想嘲笑这项服务,因为服务与DOM进行了对话.

这是我目前的测试:

describe('Player Controllers', function () {

    beforeEach(function () {
        this.addMatchers({
            toEqualData: function (expected) {
                return angular.equals(this.actual, expected);
            }
        });
    });

    describe('TestPSPlayerModule', function () {
        var $httpBackend, scope, ctrl;

        beforeEach(module('PSPlayerModule'));

        beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
            $httpBackend = _$httpBackend_;

            scope = $rootScope.$new();
            ctrl = $controller(PlayerController, { $scope: scope });
        }));

        it('should request a clip url from the server when clipClicked is called', function () {
            expect(1).toBe(1);
        });
    });

});
Run Code Online (Sandbox Code Playgroud)

我的控制器看起来像这样:

w.PlayerController = function ($scope, $http, $window, speedSlider, $location) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

所以这是我想要模仿的speedSlider.

我有想法使用我在测试代码中创建的模块,它可以提供速度滑块的伪造实现,所以我将以下内容添加到test.js文件的顶部:

module('TestPSPlayerModule', []).factory('speedSlider', function () {
    return = {
       ...
    };
});
Run Code Online (Sandbox Code Playgroud)

然后在beforeEach()调用中列出该模块而不是具体的模块,但如果我这样做,我会收到以下错误:

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

所以我认为必须有一个更好的方法来提供我的一个服务的模拟实现.我可以用sinon.js做的事....

ken*_*gen 40

还要确保你没有尝试在注入函数调用中执行此操作:

这会抛出错误:

    beforeEach(inject(function(someOtherService) {
        module('theApp', function($provide) {
            myMock = {foo: 'bar'};
            $provide.value('myService', myServiceMock);
            someOtherService.doSomething();
        });
    }));
Run Code Online (Sandbox Code Playgroud)

这不会:

    beforeEach(function() {
        module('theApp', function($provide) {
            myMock = {foo: 'bar'};
            $provide.value('myService', myServiceMock);
        });

        inject(function(someOtherService) {
           someOtherService.doSomething();
        });
    });
Run Code Online (Sandbox Code Playgroud)

  • 在`inject()`中嵌入`module()`不是导致错误的原因.实际上,所有`module()`调用都必须是_before_`injection()`. (7认同)

Dan*_*yon 6

确保在定义后使用模块时没有额外的括号.所以module('TestPSPlayer')代替module('TestPSPlayer',[]).