Unit testing of Angular’s underlying $http can be very tricky. I’ve some spent considerable time to get the unit testing up and running. What was running OK in a live application, was not working at all in a unit test. I was getting error message “No pending request to flush !” all the time.
My controller looked something like this
//TypeScript Module.controller("UsersCtrl", [<any> "$scope", "$location", "User", function ( $scope, $location : ng.ILocationService, User: ng.resource.IResourceClass) { $scope.findUsers = () => { User.query({ email: $scope.searchTerm, showAdHoc: $scope.showAdHoc }, function (data: any) { //data arrived. Do something with them }, function (errorData: any) { //server error. Notify user }); }; }]); }
And the unit test looked like this
it('should set matchedUsers.isLoading when searching', inject(function ($controller) { $httpBackend.when('GET', '/api/user?email=a&showAdHoc=false').respond({}); controller = $controller('UsersCtrl', { $scope: scope }); scope.matchedUsers.isLoading = false; scope.searchTerm = 'a'; //Method being tested scope.findUsers(); expect(scope.matchedUsers.isLoading).toBe(true); //this fails on "No pending request to flush !" $httpBackend.flush(); }));
This did not work and I just could not understand why. According to example on Angular’s doc site everything seemed fine. The problem was hidden in the underlying $http service, see documentation here.
You have to explicitly call $scope.$apply() which triggers the $digest() which takes care of the $http request.
So the working unit test code should look like this:
scope.$apply(function() { scope.findUsers(); }); //now it works $httpBackend.flush();