问题的要点是,我认为在附带的单元测试中,我没有正确访问指令的作用域和控制器。
我有一个指令,看起来像这样:
app.controller('GalleryDirectiveController', ['$scope', '$element', '$timeout', function($scope, $element, $timeout){
$scope.panels = [];
this.addPanel = function(panel){
// Timeout to help with $scope.$watch in other directives
return $timeout(function(){ $scope.panels.push(panel); }, 0);
};
}]);
app.directive('gallery', function(){
return {
restrict: 'E',
controller: 'GalleryDirectiveController'
};
});
我现在要做的是编写单元测试,模拟将自己添加到库中的库面板集合。不幸的是,我认为我在单元测试中没有正确访问控制器和指令的范围,所以它们永远不会通过
单元测试看起来像这样:
describe('app Gallery', function(){
var gallery;
var $scope;
beforeEach(module('app'));
beforeEach(inject(function($compile, $rootScope){
var element = angular.element('<gallery/>');
$compile(element)($rootScope.$new());
$rootScope.$digest();
$scope = element.isolateScope() || element.scope();
gallery = element.controller('gallery');
}));
it('should add panels to the gallery', function(){
for (var i = 0; i < 9; i++) {
gallery.addPanel({
$el : $('<div></div>')
});
}
// Each panel is added in a timeout, so I thought
// the problem might have been a timing issue
waitsFor(function(){
return $scope.panels.length !== 0;
}, 'the panels to be added', 200);
});
});
$scope.panels.length始终为零。这让我认为我在单元测试中设置的$scope变量与控制器修改的$scop变量不同。值得一提的是,其他检查gallery.addPanel和$scope.panels是否定义为预期通过的单元测试。
希望我只是错过了一些小东西。我担心的是,我可能创建了一个难以测试的画廊指令。
您可以在设置期望值之前刷新$timeout
。
即:-
var $timeout; //or var flushTimeout;
...
beforeEach(inject(function($compile, $rootScope, _$timeout_){ //<-- inject timeout
$timeout = _$timeout_; //Save it in outer scope
//or flushTimeout = _$timeout_.flush
...
在你的测试中做:-
it('should add panels to the gallery', function(){
for (var i = 0; i < 9; i++) {
gallery.addPanel({
$el : $('<div></div>')
});
}
$timeout.flush(); //or flushTimeout();
expect($scope.panels.length).toEqual(9);
});
测试演示