方案是我有一个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>
测试这个的最佳方法是什么?
答案 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);
});
});