我有一个控制器,在构造时调用附加到$scope
的方法:
angular.module('example', []).controller('exampleCtrl', function($scope) {
$scope.method = function () { ... };
$scope.method();
});
我想测试一下,在构造控制器的过程中,会调用此方法。我使用jasmine作为我的测试框架,使用sinon.js作为我的模拟框架。
describe('tests', function() {
var $scope, $controller;
beforeEach(inject(function($rootScope, _$controller_) {
$scope = $rootScope.$new();
$controller = _$controller_;
});
describe('During construction', function() {
it('should call "method"', function() {
$controller('exampleCtrl', { $scope: $scope });
var methodStub = sinon.stub($scope, 'method');
expect(methodStub.called).toBe(true);
});
});
});
这会失败,因为一旦$controller()
被调用,它就会在我能够将它存根之前立即调用$scope.method()
。但是,如果我尝试在构造之前存根该方法,
it('should call "method"', function() {
var methodStub = sinon.stub($scope, 'method');
$controller('exampleCtrl', { $scope: $scope });
expect(methodStub.called).toBe(true);
});
sinon抛出一个错误:TypeError: Cannot read property 'restore' of undefined
,因为$ scope.method没有定义,因为我还没有调用构造函数!
我还尝试直接在$scope
上删除该方法,即$scope.method = sinon.stub()
,但在控制器构建期间会被覆盖。
那么,是否可以存根构造期间调用的方法?
答案 0 :(得分:1)
它不起作用,因为控制器总是覆盖你的存根。
这是一个干净的代码问题。
首先,控制器不应包含任何复杂的逻辑。通常它会进行测试,以便您模拟依赖项并检查它们是否被正确调用。
其次,首选控制器表示法是“controller as”。因此,Controller是一个经典的JS类。如果在原型中定义方法,则可以模拟/存根。
但总的来说,要求有点不寻常,可能表明控制器太过分了。