用sinon存根在角控制器构造中调用的范围方法
Stubbing a scope method invoked in angular controller construction with sinon
我有一个控制器,在构建时调用附加到$scope
的方法:
angular.module('example', []).controller('exampleCtrl', function($scope) {
$scope.method = function () { ... };
$scope.method();
});
我想测试在控制器的构造过程中,这个方法被调用。我使用jasmine作为我的测试框架,使用sinon.js作为我的mock框架。
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。方法没有定义,因为我没有调用构造函数!
我还尝试直接在$scope
(即$scope.method = sinon.stub()
)上存根方法,但在控制器构造期间会被覆盖。
那么,在构造期间调用的方法是否可能存根?
这是行不通的,因为控制器总是覆盖你的存根。
这更像是一个代码整洁的问题。
首先,控制器不应该包含任何复杂的逻辑。通常它会进行测试,以便模拟依赖项并检查它们是否被正确调用。
其次,首选控制器符号是"controller as"。因此Controller是一个经典的JS类。如果你在原型中定义了方法,你可以模拟/存根它。
但是一般来说,这个要求有点不寻常,可能表明控制器做得太多了。
相关文章:
- 日志:未捕获的范围错误:超过了最大调用堆栈大小
- 未捕获的范围错误:setTimeout()超过了最大调用堆栈大小
- JavaScript继承:未捕获的范围错误:超过了最大调用堆栈大小
- 收到“范围错误: 超出最大调用堆栈大小”错误
- 为什么我从 JSLint 获得从事件调用的函数的“超出范围”
- 在 JavaScript 中捕获调用方的范围
- 递归承诺调用 - 内存范围变量问题
- 是否可以对超出范围的 setInterval 变量调用 clearInterval 方法
- 如何更改对 javascript 属性的调用的范围/上下文
- 从全局范围调用 jQuery 中的函数
- 从脚本标记的全局范围调用webpack模块中的函数
- Angular.js的多个rest调用范围问题
- 在指令外部调用范围变量
- 如何从 ui-grid 中显示的按钮调用范围方法 - 在 Angular js 中
- 使用字符串作为函数调用范围
- 有没有办法在函数中重新分配参数,并让它也影响调用范围
- 在 Angular 指令中的事件处理程序中调用范围函数
- 如何从 ngGrid 中显示的按钮调用范围方法
- 从指令生成的html中调用范围内的函数
- Javascript函数调用范围