AngularJS+Jasmine: $httpBackend not working as expected
angularjs, jasmine, karma-runner, service, unit-testing
Solution
Let's talk about each error separately:
Error: No pending request to flush!
That's happening because no request was made through `$httpBackend`, so there's nothing to flush. That's because you are instantiating `UserService` before `$httpBackend` and so Angular doesn't know it should use it instead of the real `$http`. If you check out the console you'll see that a real request is being sent.
Error: Unsatisfied requests: GET https://api.github.com/users/wilk
Same reason as the above. Since `$httpBackend` isn't being used by the service, the expectation you've created is never fulfilled.
Here's your spec refactored after considering all of the above:
describe ('Service: UserService', function () {
var UserService,
GITHUB_API_URL,
GITHUB_USER,
$httpBackend;
beforeEach(function() {
module('plunker');
inject(function( _$httpBackend_, _UserService_, _GITHUB_API_URL_, _GITHUB_USER_) {
$httpBackend = _$httpBackend_;
UserService = _UserService_;
GITHUB_API_URL = _GITHUB_API_URL_;
GITHUB_USER = _GITHUB_USER_;
});
});
afterEach (function () {
$httpBackend.verifyNoOutstandingExpectation ();
$httpBackend.verifyNoOutstandingRequest ();
});
describe ('when populate method is called', function () {
it ('should returns user data', function () {
$httpBackend
.whenGET(GITHUB_API_URL + '/users/' + GITHUB_USER)
.respond ({
login: GITHUB_USER,
id: 618009
});
UserService.populate(GITHUB_USER);
$httpBackend.flush();
expect(UserService.data().login).toBe(GITHUB_USER);
expect(UserService.data().id).toBe(618009);
});
});
});
Plunker
Note: I've changed the way things were being injected a little bit, but the way you are doing is just fine, as long as you create `$httpBackend` before everything else.
Problem
I'm using Jasmine with Karma to test my app built on Angular. I've to test a service that loads user data and I'm using $httpBackend to mock the responses. However, when I run the test, I got two errors: - Error: No pending request to flush! - Error: Unsatisfied requests: GET https://api.github.com/users/wilk Module: ``` 'use strict'; app.service ('UserService', ['$resource', '$q', 'GITHUB_API_URL', function ($resource, $q, GITHUB_API_URL) { var userResource = $resource (GITHUB_API_URL + '/users/:user', {user: '@user'}) , userModel = {}; return { data: function () { return userModel; } , populate: function (user) { var deferred = $q.defer () , userRequest = userResource.get ({user: user}); $q .when (userRequest.$promise) .then (function (data) { userModel = data; deferred.resolve (data); }); return deferred.promise; } }; }]); ``` Test: ``` 'use strict'; describe ('Service: UserService', function () { beforeEach (module ('myApp')); var $appInjector = angular.injector (['myApp']) , UserService = $appInjector.get ('UserService') , GITHUB_API_URL = $appInjector.get ('GITHUB_API_URL') , GITHUB_USER = $appInjector.get ('GITHUB_USER') , $httpBackend; beforeEach (inject (function ($injector) { $httpBackend = $injector.get ('$httpBackend'); $httpBackend .when ('GET', GITHUB_API_URL + '/users/' + GITHUB_USER) .respond ({ login: GITHUB_USER , id: 618009 }); })); afterEach (function () { $httpBackend.verifyNoOutstandingExpectation (); $httpBackend.verifyNoOutstandingRequest (); }); describe ('when populate method is called', function () { it ('should returns user data', function () { $httpBackend.expectGET (GITHUB_API_URL + '/users/' + GITHUB_USER); UserService.populate (GITHUB_USER); $httpBackend.flush (); expect(UserService.data ()).toEqual ({ login: GITHUB_USER , id: 618009 }); }); }); }); ``` Let's assume that GITHUB_API_URL is equal to 'https://api.github.com/' and GITHUB_USER is equal to 'wilk'. I'm running this test with Karma-Jasmine 0.1.5 and AngularJS 1.2.6 (with Angular Mocks and Scenario 1.2.6). What's wrong with this code?