我想测试这个功能:
function initializeView() {
var deferred = $q.defer();
if(this.momentArray) {
core.listMoments(constants.BEST_MOMENT_PREFIX, '').then(function(moments) {
//Ommitted
deferred.resolve(moments);
}, function(error) {
console.log("ERROR");
deferred.reject(error);
});
}
else {
deferred.resolve();
}
return deferred.promise;
};
函数调用core.listMoments:
function listMoments(prefix, startAfter) {
// var deferred = $q.defer();
var promises = [];
return awsServices.getMoments(prefix, startAfter).then(function(moments) { //Mocked
console.log("getMoments Returned"); //Does not print
for(var i = 0; i < moments.length; i++) {
// moments[i].Key = constants.IMAGE_URL + moments[i].Key;
promises.push(getMomentMetaData(moments[i]));
}
return $q.all(promises);
});
};
这是我的测试函数:
it('Should correctly initialize the view', function(done) {
spyOn(awsServices, 'getMoments').and.callFake(function() {
console.log("getMoments Has been mocked"); //This prints
return $q.resolve(mock_moment);
});
service.initializeView().then(function() {
done();
})
});
问题出在 awsServices 的“getMoments”模拟上。对 awsServices.getMoments 的调用在 listMoments 函数中。我想模拟这个函数,但是当我这样做时它不会执行 promise 的“then”部分。
因此,根据我的控制台日志,它会打印“getMoments Has been mocked”日志,但不会打印“getMoments Returned”日志。所以这个函数被模拟了,但由于某种原因它没有进入 then 语句,我的测试只是超时了。
最佳答案
为了让 promise 的 .then()
部分在这样的测试中工作,您需要使用 $rootScope.$apply()
。无论 promise 是在您的测试代码中还是在被测试的引用库中,这都是必需的。可以把它想象成 $http
或 $timeout
调用的 flush()
函数。
Angular documentation's $q page 中的测试示例显示如何使用它:
it('should simulate promise', inject(function($q, $rootScope) {
var deferred = $q.defer();
var promise = deferred.promise;
var resolvedValue;
promise.then(function(value) { resolvedValue = value; });
expect(resolvedValue).toBeUndefined();
// Simulate resolving of promise
deferred.resolve(123);
// Note that the 'then' function does not get called synchronously.
// This is because we want the promise API to always be async, whether or not
// it got called synchronously or asynchronously.
expect(resolvedValue).toBeUndefined();
// Propagate promise resolution to 'then' functions using $apply().
$rootScope.$apply();
expect(resolvedValue).toEqual(123);
}));
请注意,它们注入(inject)了 $rootScope
。
关于javascript - Jasmine 测试不会进入 promise 的 then 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46029880/