我的控制器中有以下功能:
function putActivities () {
var promises = [];
view.activities.forEach(function (activity) {
promises.push(API.putActivities({activity: activity}).$promise);
});
$q.all(promises).then(function () {
view.finished = true;
});
}
其中API是$资源。此方法由以下代码段进行测试:
describe('putActivities', function() {
beforeEach(function() {
view.activities = ['hello'];
spyOn(API, 'putActivities').and.callFake(function () {
return {
$promise: q(function () {})
}
});
});
it('view is finished after putting activities', function() {
view.putActivities();
expect(view.finished).toEqual(true);
});
});
由于某种原因,$ q.all永远不会解析,view.finished
永远不会设置为true。有谁知道为什么会发生这种情况以及我如何解决它?
答案 0 :(得分:1)
间谍返回的假承诺需要手动解决(或拒绝)。
不确定间谍中的q
函数是做什么的,但我会在示例中使用Angular的$q
:
beforeEach(function() {
view.activities = ['hello'];
mockedPromises = [];
spyOn(API, 'putActivities').and.callFake(function() {
var defer = $q.defer();
mockedPromises.push(defer);
return {
$promise: defer.promise
};
});
});
现在您可以访问测试中的promise,并可以解析或拒绝它们,具体取决于您要测试的场景:
it('view is finished after putting activities', function() {
view.putActivities();
mockedPromises.forEach(function(promise) {
promise.resolve();
});
$rootScope.$apply();
expect(view.finished).toEqual(true);
});
请注意,在测试promises时(至少使用$q
服务),promises的解析与摘要周期相关联,这意味着then
函数仅在摘要具有后才会被调用运行
测试时,您需要手动触发摘要周期(这样您可以更好地控制流量)。这就是$rootScope.$apply()
的作用。