Reputation: 65
I am doing some Jasmine testing using angular promises and have a question related to timing. Found an answer here Unit-test promise-based code in Angular, but need clarification about how this works. Given that the then
method is always handled in an asynchronous way how is the following test guaranteed to pass. Isn't there are risk that the expect
will run ahead of the then
block being executed and run the expect before the value has been assigned. Or... does the digest cycle guarantee that the value will be assigned before the expect runs. Meaning, a digest cycle will effectively behave like a blocking call that guarantees that the promises are all resolved before the code is allowed to proceed.
function someService(){
var deferred = $q.defer();
deferred.resolve(myObj);
return deferred.promise;
}
it ('testing promise', function() {
var res;
var res2;
someService().then(function(obj){
res = "test";
});
someService().then(function(obj){
res2 = "test2";
});
$rootScope.$apply();
expect(res).toBe('test');
expect(res2).toBe('test2');
});
Upvotes: 0
Views: 1190
Reputation: 8323
While Michal's answer points to the right idea, the key here is that $apply()
is called on the pertinent scope. Here's the example from the Angular docs:
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);
}));
Upvotes: 0
Reputation: 26982
a digest cycle will effectively behave like a blocking call that guarantees that the promises are all resolved before the code is allowed to proceed.
Yes, although more accurately it would guarantee that the success callbacks of resolved promises would have run.
There is a very similar example that shows how the digest cycle is tied to the success callbacks of promises in the docs for $q
Upvotes: 1