Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve $q.all promises in Jasmine unit tests?

My controller has code like below:

$q.all([qService.getData($scope.id), dService.getData(), qTService.get()]) .then(function (allData) {   $scope.data1 = allData[0];   $scope.data2 = allData[1];   $scope.data3 = allData[2]; }); 

And in my unit tests i am doing something like this:

beforeEach(inject(function($rootScope, $q, $location){// and other dependencies...    qServiceSpy = spyOn(_qService, 'getData').andCallFake(function () {     var data1 = {       id: 1,       sellingProperty: 1,     };     var d = $q.defer();     d.resolve(data1);     return d.promise;   });    dServiceSpy = spyOn(_dService, 'getData').andCallFake(function () {     var data2 = [{ "id": "1", "anotherProp": 123 }];     var d = $q.defer();     d.resolve(data2);     return d.promise;   });   qTServiceSpy = spyOn(_qTService, 'get').andCallFake(function () {     var data3 = [{ id: 0, name: 'Rahul' }];     var d = $q.defer();     d.resolve(data3);     return d.promise;   });   rootScope = $rootScope; }); 

Now in my test i am checking if services are called and the data1, data2 are not undefined..

it('check if qService' got called, function() {   expect(scope.data1).toBeUndefined();   rootScope.$digest();   expect(_quoteService.getQuote).toHaveBeenCalled(); }); it('check if "data1" is defined', function () {   expect(scope.data1).toBeUndefined();   rootScope.$digest();   expect(scope.data1).toBeDefined(); }); 

my problem is, this was working fine until i replaced my individual service calls in controller with q.all and in tests scope.$apply with rootScope.$digest. With q.all and rootScope.$digest (tried using scope.$apply as well) both tests fails with error:

10 $digest() iterations reached. Aborting!

if i remove rootScope.$digest then the promises never get resolves and tests fails saying

expected undefined to be defined.

Any help how should i unit tests code with q.all?

came across this post

But that also doesn't help as i am already trying to use $digest.

like image 239
Rahul R. Avatar asked May 01 '13 11:05

Rahul R.


People also ask

How do you test promise reject Jasmine?

describe('test promise with jasmine', function() { it('expects a rejected promise', function() { var promise = getRejectedPromise(); // return expect(promise). toBe('rejected'); return expect(promise. inspect(). state).

What is done () in Jasmine?

If the function passed to Jasmine takes an argument (traditionally called done ), Jasmine will pass a function to be invoked when asynchronous work has been completed.


1 Answers

You can try putting $rootScope.$apply() in an afterEach() callback function. Promises resolve on $apply() in Angular.

afterEach(function(){     rootScope.$apply(); }); 
like image 197
Thomas Schultz Avatar answered Oct 29 '22 12:10

Thomas Schultz