Mat*_*aNg 3 javascript unit-testing jasmine angularjs
我想测试这个功能:
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;
};
Run Code Online (Sandbox Code Playgroud)
该函数调用 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);
});
};
Run Code Online (Sandbox Code Playgroud)
这是我的测试功能:
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();
})
});
Run Code Online (Sandbox Code Playgroud)
问题在于 awsServices 'getMoments' 模拟。对 awsServices.getMoments 的调用位于 listMoments 函数中。我想模拟这个函数,但是当我这样做时,它不会执行承诺的“then”部分。
因此,根据我的控制台日志,它会打印“getMoments Has been mocked”日志,但不会打印“getMoments Returned”日志。所以这个函数被模拟了,但由于某种原因它没有进入 then 语句,我的测试只是超时。
小智 5
为了让.then()承诺的一部分在这样的测试中工作,你需要使用$rootScope.$apply(). 无论承诺是在您的测试代码中还是在正在测试的引用库中,这都是必需的。可以把它想象成flush()for$http或$timeoutcall的函数。
Angular 文档的 $q 页面中的测试示例展示了如何使用它:
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);
}));
Run Code Online (Sandbox Code Playgroud)
请注意,它们注入$rootScope.