我花了很多时间尝试对一个指令进行单元测试,该指令在控制器中生成/跟踪一个承诺,这里可以看到如何实现这一点的示例:https://plnkr.co/edit/d8wMq0qlpiE4P25q5lhB
指令:
.directive('testDirective', function() {
return {
scope: {
save: '&',
},
template: '<div><a href="#" ng-click="handleSave($event)">Click Here</a></div>',
link: function(scope, element, attr, controllers) {
scope.someData = {
saving: false
};
scope.handleSave = function() {
scope.someData.name = parseInt(Math.random() * 100);
scope.someData.saving = true;
scope.someData.error = false;
scope.someData.id = null;
return scope.save()(scope.someData)
.then(function(data) {
scope.someData = data;
})
.catch(function(err) {
scope.someData.error = true;
})
.finally(function() {
scope.someData.saving = false;
});
};
}
};
})
控制器:
.controller('TestCtrl', function($scope, $q, $timeout) {
$scope.saveCtrl = function(directiveData) {
return $q(function(resolve, reject) {
$timeout(function() {
if (Math.round(Math.random())) {
directiveData.id = parseInt(Math.random() * 100);
resolve(directiveData);
} else {
reject(new Error());
}
}, 2000)
});
}
});
模板:
<test-directive save="saveCtrl"></test-directive>
它作为一个组件起作用,如示例中所示,但测试无法完成,因为.finally()永远不会被调用。我已经尝试了很多变化来强制$ digest,但似乎没有任何东西可以完成承诺。
答案 0 :(得分:0)
想想我明白了。 https://plnkr.co/edit/CBvrZo4g9LjJC61VV0wp
```
$scope.saveCtrl = function(data) {
return $q(function(resolve, reject) {
setTimeout(function() {
if (Math.round(Math.random())) {
var id = parseInt(Math.random() * 100);
resolve(id);
} else {
reject(new Error());
}
elementScope.$apply();
$scope.$apply();
}, 100);
});
};
```
第39行有一个未定义的var,角度超时表现得很奇怪。这应该导致指令的完整流程保存以使用超时进行测试。我认为可能不需要超时,因为您可以假设即时超时情况而不会丢失任何测试。