How to mock an angular $http call and return a promise object that behaves like $http
Just use the deferred
method of the $q
service
var fakeHttpCall = function(isSuccessful) { var deferred = $q.defer() if (isSuccessful === true) { deferred.resolve("Successfully resolved the fake $http call") } else { deferred.reject("Oh no! Something went terribly wrong in your fake $http call") } return deferred.promise }
And then you can call your function like an $http
promise (you have to customize whatever you want to put inside of it, of course).
fakeHttpCall(true).then( function (data) { // success callback console.log(data) }, function (err) { // error callback console.log(err) })
I found that this post is similar to what I was asking.
However, I wanted a way to mock my service call so that fake data could be returned instead of issuing a true HTTP request call. The best way to handle this situation, for me, is to use angular's $httpBackend
service. For example, to bypass a GET request to my "items" resource BUT to not bypass GETs of my partials/templates I would do something like this:
angular .module('myApp', ['ngMockE2E']) .run(['$httpBackend', function($httpBackend) { $httpBackend .whenGET(/^partials\/.+/) .passThrough(); $httpBackend .whenGET(/^\/myapp\/items\/.+/) .respond({itemId : "123", name : "ItemName"});}]);
See this documentation for more information on $httpBackend.
I finally found a way using jasmin. $httpBackend
was no option for me, as there were also non-$http-methods I needed mock on the same service. I also think that the controller test needing to specify the url is not perfect as imho the controller and its test should not need to know about it.
Here is how it works:
beforeEach(inject(function ($controller, $rootScope, $q) { scope = $rootScope.$new(); mockSvc = { someFn: function () { }, someHttpFn: function () { } }; // use jasmin to fake $http promise response spyOn(mockSvc, 'someHttpFn').and.callFake(function () { return { success: function (callback) { callback({ // some fake response }); }, then: function(callback) { callback({ // some fake response, you probably would want that to be // the same as for success }); }, error: function(callback){ callback({ // some fake response }); } } }); MyCtrl = $controller('MyCtrl', { $scope: scope, MyActualSvc: mockSvc });}));