How to resolve a promise in Angular unit test

I use the basic karma / jasmine setting to check my Angular code. Here is my test:

var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q; describe('main controller', function() { var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q; beforeEach(inject(function($controller, $rootScope, $q) { scope = $rootScope.$new(); $controllerConstructor = $controller; q = $q; mockSuperheroData = { getSuperheroes: function() { deferred = q.defer(); return deferred.promise; } }; ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}}); })); it('should set the result of getResource to scope.heroes', function() { scope.getHeroes(); expect(scope.heroes).toBe(100); }); } 

scope.getHeroes() calls mockSuperheroData.getSuperheroes() , which returns a promise. How to make a promise to return what I want in unit test? Where can I make a promise to scoff at his return?

+6
source share
2 answers

How to make a promise to return what I want in unit test?

Basically you will need to call resolve in deferred :

 deferred.resolve(100); 

You can put this immediately before return deferred.promise or asynchronous setTimeout .

+4
source
 var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q; describe('main controller', function() { var $controllerConstructor, ctr, mockSuperheroData, scope, deferred, q, rootScope; beforeEach(inject(function($controller, $rootScope, $q) { scope = $rootScope.$new(); $controllerConstructor = $controller; q = $q; rootScope = $rootScope; mockSuperheroData = { getSuperheroes: function() { deferred = q.defer(); return deferred.promise; } }; ctr = $controllerConstructor('MainCtrl', {$scope: scope, $location: {}, superheroService: mockSuperheroData, keys: {}}); })); it('should set the result of getResource to scope.heroes', function() { scope.getHeroes(); deferred.resolve(100); rootScope.$apply(); expect(scope.heroes).toBe(100); }); }); 

It should be noted that since $ q is integrated with $ rootScope, you not only need to allow the pending object, but you also need to propagate the changes by invoking $ rootScope. $ apply.

I wrote a blog about the mock angular promises in projectpoppycock

and I wrote a working example with plunkr tests

I really like the way you enter the service layout as a controller dependency using the $ controller service, I may have to reconsider my way of doing this. Your way is better :) Thank you!

+2
source

All Articles