Check out myAngular article series with live demos and Facebook group Angular - Advanced Topics

How to mock http calls in Angular

Torgeir "Tor" Helgevold
- JavaScript Developer and Blogger
Published: Sun May 10 2015

For better testability, and other important reasons, it's generally advisable to add some form of abstraction around your http access layer. However, Angular offers its own “hook” for mocking if your code under test has a direct dependency on the $http service. In this post I will show how to tap into Angular's httpBackend service to define mocked responses to http requests.

In the code below I have defined a simple greeting controller for retrieving greetings from the server through an ajax call.

angular.module('app').controller('greetingController',[
        '$http',
        '$scope',
        function($http,$scope){
            $http.get('http:/localhost:3000/getGreeting').then(function(result){
                $scope.greetings = result.data;
            });
}]);

At first glance this code looks challenging to test due to the tight coupling between the controller and the ajax call. However, it turns out that Angular can help us out here through its own abstraction layer in the $http service.

The solution is to use the built in $httpBackend service to define a mock response. Below is a simple demonstration of how this can be done.

describe('greetingTest', function(){
    var greetings = [{message:'hello friend'}];
    var $controller;
    var $scope;
    var $httpBackend;
    var $q;
    beforeEach(function() {

        module('app');

        inject(function ($injector) {
            $scope = $injector.get('$rootScope').$new();
            $controller = $injector.get('$controller');
            $httpBackend = $injector.get('$httpBackend');
            $q = $injector.get('$q');
        });

    });
    it('should load mocked greetings', function(){

        $httpBackend.whenGET('http:/localhost:3000/getGreeting').respond(200, greetings);
        $controller('greetingController',{'$scope':$scope});
        $httpBackend.flush(); //needed to resolve and handle promise returned by $http

        expect($scope.greetings).toEqual(greetings);
    });
});

After injecting the necessary dependencies, all you have to do is call $httpBackend.whenGET to define the response.

If you liked this article, share it with your friends on social media:

We also have a new Facebook group about advanced Angular topics.

I invite you to follow me on twitter