How to mock an angular $http call and return a promise object that behaves like $http How to mock an angular $http call and return a promise object that behaves like $http angularjs angularjs

How to mock an angular $http call and return a promise object that behaves like $http


Just use the deferred method of the $qservice

    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  });}));