单元测试AngularJS控制器,它通过$ controller从基本控制器继承

时间:2014-12-04 15:01:37

标签: angularjs unit-testing inheritance jasmine

方案是我有一个ChildCtrl控制器,它继承this inheritance pattern之后的BaseCtrl

angular.module('my-module', [])
    .controller('BaseCtrl', function ($scope, frobnicate) {
        console.log('BaseCtrl instantiated');

        $scope.foo = frobnicate();

        // do a bunch of stuff
    })

    .controller('ChildCtrl', function ($controller, $scope) {
        $controller('BaseCtrl', {
            $scope: $scope,
            frobnicate: function () {
                return 123;
            }
        });
    });

假设BaseCtrl做了很多事情并且已经经过充分测试,我想测试ChildCtrl使用某些参数实例化BaseCtrl。我最初的想法是这样的:

describe("ChildCtrl", function () {
    var BaseCtrl;

    beforeEach(module('my-module'));

    beforeEach(module(function($provide) {
        BaseCtrl = jasmine.createSpy();
        $provide.value('BaseCtrl', BaseCtrl);
    }));

    it("inherits from BaseCtrl", inject(function ($controller, $rootScope) {
        $controller('ChildCtrl', { $scope: $rootScope.$new() });

        expect(BaseCtrl).toHaveBeenCalled();
    }));
});

然而,当我运行测试时,间谍永远不会被调用,控制台显示“BaseCtrl instantiated”,表明$controller正在使用实际控制器而不是我提供$provide.value()的实例。 / p>

测试这个的最佳方法是什么?

1 个答案:

答案 0 :(得分:5)

因此看起来$controller不会在$provide.value()命名空间中按名称搜索控制器。相反,您必须使用$controllerProvider.register()方法,该方法只能从module.config()块访问。幸运的是,我们可以使用一个钩子来访问被测模块上的$controllerProvider

更新后的测试代码如下:

describe("ChildCtrl", function () {
    var BaseCtrl;

    beforeEach(module('my-module', function ($controllerProvider) {
        BaseCtrl = jasmine.createSpy();
        BaseCtrl.$inject = ['$scope', 'frobnicate'];

        $controllerProvider.register('BaseCtrl', BaseCtrl);
    }));

    beforeEach(inject(function ($controller, $rootScope) {
        $controller('ChildCtrl', { $scope: $rootScope.$new() });
    }));

    it("inherits from BaseCtrl", inject(function ($controller, $rootScope) {
        expect(BaseCtrl).toHaveBeenCalled();
    }));

    it("passes frobnicate() function to BaseCtrl that returns 123", function () {
        var args = BaseCtrl.calls.argsFor(0);
        var frobnicate = args[1];

        expect(frobnicate()).toEqual(123);
    });
});