我有一个控制器,当前在加载相关视图时正在调用RESTful API。因此,我不确定这个问题是否与我的测试方式或代码本身的实现有关-我会对所有从整体上解决该问题的建议感到满意,例如,请帮助我-测试代码可以满足我的要求:)
以下是一些样本来说明我的观点:
控制器:
angular.module('app.myModule',[])
.controller('MyController', function($scope) {
$scope.notTestingThis = function() {
var thisFails = $scope.do.not.want.to.mock.these.objects.substr(0,10);
};
$scope.testingThis = function(myString) {
$scope.newString = myString;
};
$scope.notTestingThis();
});
测试(按现状):
describe('MyControllerTest', function() {
beforeEach(module('app.myModule'));
var $controller;
beforeEach(inject(function(_$controller_) {
$controller = _$controller_;
}));
describe('$scope.testingThis()', function() {
it('sets newString', function() {
$scope = {
'notTestingThis': {}
};
var myController = $controller('MyController', {$scope: $scope});
});
});
});
加载此视图时,我需要以某种方式调用notTestingThis函数,但是在我的单元测试中,我想隔离testingThis函数。问题是,当我在测试中初始化控制器时,它当然会调用notTestingThis并尝试对不存在的对象(在此测试中我并不关心的对象)执行操作。
显然,按照该示例尝试存入有问题的函数没有用,因为初始化时会重写$ scope。有没有办法在您要测试的控制器中存根或模拟单个功能,或者我错过了某个地方的要点?一位同事提出的一些建议是:
增强控制器以了解单元测试本身,使您可以基于注入的模拟来调整程序流,即控制器中的以下内容:
if (!$scope.methodA) {
$scope.methodA = function() {...}
}
... 或者 ...
改变的方式notTestingThis函数被调用,通过听从$ rootScope初始化事件,而不是直接调用它,这让我嘲笑$ rootScope所以它不会触发该事件,从而防止notTestingThis被称为
我不禁觉得自己好像在想错了。有什么见解吗?
只是加倍查询,以防其他查询出现。我仔细研究了这两项建议,在实施时都与我的原始评论有所不同(因为我对这些建议有误解),即:
选项1
而不是包装每个函数,而是将调用代码包装在:
if(!testingBoolean) { $scope.notTestingThis(); };
使用testingBoolean为false,除非作为(可选)参数传递给Controller,从而允许测试代码阻止调用
选项2:
使用服务功能从$ rootScope进行$ broadcast。在该事件上将调用代码包装在侦听器中,然后从控制器调用该函数。在执行测试时模拟$ rootScope将阻止notTestingThis函数被触发。
真正的解决方案
但是,这些方法似乎分散了注意力。尽管未在任何地方明确声明,但看来控制器不应该自己调用函数。正确的选择似乎是重新设计应用程序设计,以便指令可以通过绑定调用函数,从而简化了单元测试。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句