Hitting real angular http service from jasmine test
Sometimes you want to use jasmine as a tool for playing with existing web services, grab some responses and then convert them into the stubs. Unfortunately, from jasmine test you have access only to mocked version of $httpBackend service.
You can use this helper code for accessing real $httpBackend service:
angular.module('httpReal', ['ng'])
.config(['$provide', function($provide) {
$provide.decorator('$httpBackend', function() {
return angular.injector(['ng']).get('$httpBackend');
});
}])
.service('HttpReal', function($rootScope) {
this.submit = function() {
$rootScope.$digest();
};
}
);
This code creates httpReal service in which you restore access to original $httpBackend. It also provides a function to flush the request. Otherwise promises from http service call will never be executed.
Let’s create demo service:
var namespace = angular.module('myModule', []);
namespace.service('MyService', function($http) {
this.remoteCall = function() {
return $http({method: 'GET', url:
'http://api.openweathermap.org/data/2.5/weather?q=Princeton'});
};
});
and test it:
describe('MyService', function() {
var myService, httpReal;
beforeEach(module('myModule', 'httpReal'));
beforeEach(inject(function(MyService, HttpReal) {
myService = MyService;
httpReal = HttpReal;
}));
it('calls success callback and returns valid data',
function(done) {
myService.remoteCall().then(function(response) {
expect(response.data.sys.country).toEqual('US');
done();
});
httpReal.submit();
}
);
it('calls error callback', function(done) {
var myServiceResults = createPromise({}, false);
spyOn(myService, 'remoteCall').and.returnValue(myServiceResults);
myService.remoteCall().then(angular.noop, function() {
done();
});
httpReal.submit();
});
});
function createPromise(value, success) {
var q;
inject(function($q) {
q = $q;
});
var deferred = q.defer();
if(success === undefined || success == true) {
deferred.resolve(value);
}
else {
deferred.reject();
}
return deferred.promise;
Take a look on how to properly use promises in tests. It uses done function. In jasmine 2.x they have dropped runs/waitsFor functions in favor of the Mocha done callback. You can use it in beforeEach, afterEach and it calls.