Testing $q promises with Angular
26 Dec 2014I've been working on a few Angular projects lately, and had to test some $q
promises. And there was one little thing in how Angular implementation of $q
and the $digest
cycle interact that bit me once or twice.
If you ever fire a promise using $q
in one of your tests, know that Angular will not resolve it until you tell it to. It means that your promise will stay in an undefined state (neither resolved nor rejected) and your test will surely fail. This is because Angular promises are tied to the $scope
lifecycle and as we do not have one when running our tests, we have to add a bit of plumbing.
To force Angular to finish every promise, just add the following afterEach
implementation :
afterEach(inject(function ($injector) {
$injector.get('$rootScope').$digest();
}));
But this has a side-effet of triggering all your promises, even those you forgot about, like loading the templateUrl
for your directives. This will in turn block your tests because some promises will fail. The easiest way to correct this is to mock the responses and always respond an empty object.
beforeEach(inject(function($injector) {
$injector.get('$httpBackend').whenGET(/.*/).respond({});
}));
Hope this little tricks helped.
Want to add something ? Feel free to get in touch on Twitter : @pixelastic