我花了一大堆时间试图单元测试一个指令,该指令在控制器内生成/跟踪一个承诺,这是如何完成的一个例子可以在这里看到: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()永远不会被调用。我已经尝试了很多变化来强制$摘要,但似乎没有完成承诺。
我是一个角度n00b,有没有办法将一个指令注入测试并直接调用'link'方法,或者你是否需要编译和消化它来评估它? – dm03514
为最小可行的测试,是否有可能从'saveCtrl'中删除$超时,所以承诺立即解决?并通过不使用随机的??从测试中消除非确定性。理想情况下,可以有2个单独的测试,一个“拒绝”分支和一个“分支”分支? – dm03514
@ dm03514当然,我将它添加到实际指令中的功能以重新创建异步调用,您可以完全删除超时并立即解决/拒绝。调用'link'方法的唯一好方法就是通过这些编译的指令,但是你总是可以将可测试的功能分割成单独的'controller'。 – spaceribs