我已经发现,以测试这种类型的场景被移动到待测试移至单独的依赖性的方法,则在控制器中注入它,并提供在试验中假代替的唯一方法。
这是一个非常基本的工作例如:
angular.module('test', [])
.factory('loadResponses', function() {
return function() {
//do something
}
})
.controller('aCtrl', ['$scope', 'loadResponses', function($scope, loadResponses) {
$scope.loadResponses = loadResponses;
$scope.loadResponses();
}]);
describe('test spec', function(){
var scope;
var loadResponsesInvoked = false;
var fakeLoadResponses = function() {
loadResponsesInvoked = true;
}
beforeEach(function() {
module('test', function($provide) {
$provide.value('loadResponses', fakeLoadResponses)
});
inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$controller('aCtrl', { $scope: scope });
});
});
it('should ensure that scope.loadResponses was called upon instantiation of the controller', function() {
expect(loadResponsesInvoked).toBeTruthy();
});
});
对于您可能需要额外的工作(例如,你可能不总是希望伪造loadResponses
法)现实世界中的代码,但你的想法。
而且,这里是一个很好的文章,介绍如何创建一个实际使用茉莉花间谍假依赖关系:Mocking Dependencies in AngularJS Tests
编辑:这里是另一种方式,即使用$provide.delegate
并不会取代原来的方法:
describe('test spec', function(){
var scope, loadResponses;
var loadResponsesInvoked = false;
beforeEach(function() {
var loadResponsesDecorator = function ($delegate) {
loadResponsesInvoked = true;
return $delegate;
}
module('test', function($provide) {
$provide.decorator('loadResponses', loadResponsesDecorator);
});
inject(function($controller, $rootScope) {
scope = $rootScope.$new();
$controller('aCtrl', { $scope: scope });
});
});
it('should ensure that scope.loadResponses was called upon instantiation of the controller', function() {
expect(loadResponsesInvoked).toBeTruthy();
});
});
它通常会工作,但不会在这种情况下。因为你在控制器被实例化并调用了方法之后设置了间谍。即使你在作用域上创建了一个间谍方法,它也会在控制器被实例化时被覆盖,并且它不会真正起作用。 – PSL 2014-09-24 20:16:28
当我想到它时,你不需要测试初始化时是否调用了'$ scope.loadResponses'。因为如果你的控制器实例化成功(没有它,反正你的测试都不会通过),所以保证'$ scope.loadResponses'已被调用。所以我没有看到在初始化函数上进行间谍活动。 – PSL 2014-09-24 20:49:28
在路上,我不希望开发人员将其删除(有意或无意),因为它获得了使用该页面的关键资源。我能够检查一个变量是否在初始化后被分配了预期的值,我有点惊讶,我无法使用间谍来检查初始化调用。 – 2014-09-24 21:09:23