title: TypeError: service.getForums() is not a function - jasmine unit testing for AngularJS
body: <p>Hello I am new to AngularJS. I am trying to test angular service <code>ForumService</code>. For that I have to mock the response that I get while calling the service method. I did something but I don't know if its right or not. I am getting an error </p>
  
  <blockquote>
    <p>"ForumService should use Function FAILED"<br>
    "TypeError: service.getForums is not a function"</p>
  </blockquote>
  
  <p>This is the service that I am testing</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>(function() {
    'use strict';
  
    function ForumService($q, $http, config, Forum) {
      var service = {};
  
      /**
       * Sends a GET request to backend API for all forums.
       *
       * @return {Promise}
       */
      service.getForums = function(onSuccessCallback, onErrorCallback) {
  
        $http.get(config.apiBaseUrl + '/api/forums')
          .then(
            function handleSuccess(response) {
              onSuccessCallback(response.data.data);
            },
            function handleError(response) {
              onErrorCallback(response.data.error);
            }
          );
      };
      /**
       * Sends a GET request to backend API for all forums.
       *
       * @return {Promise}
       */
      service.getForumsPromise = function() {
        var q = $q.defer();
  
        $http.get(config.apiBaseUrl + '/api/forums')
          .then(
            function success(response) {
              q.resolve(buildForumArray(response.data.data));
            },
            function error(response) {
              q.reject(response.data.error);
            }
          );
  
        return q.promise;
      };
  
      function buildForumArray(data) {
        var forumArray = [];
  
        data.forEach(function(forumData) {
          forumArray.push(new Forum(forumData));
        });
  
        return forumArray;
      }
  
      return service;
    }
  
    ForumService.$inject = [
      '$q',
      '$http',
      'config',
      'Forum'
    ];
  
    angular
      .module('app.services')
      .factory('ForumService', ForumService);
  })();</code></pre>
  </div>
  </div>
  </p>
  
  <p>The following is the code where I am testing the first method <code>service.getForums()</code></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>'use strict';
  
  describe('ForumService', function() {
  
    var service, $q, config, httpBackend;
    beforeEach(module('app.services'));
    beforeEach(module('app.models'));
  
    beforeEach(module(function($provide) {
  
      $provide.service('config', function() {
  
        this.apiBaseUrl = "localhost";
  
      });
  
      $provide.service('ForumService', function() {
  
        this.constructor = jasmine.createSpy('ForumService')
  
      });
  
      $provide.service('Forum', function() {
  
        this.constructor = jasmine.createSpy('Forum')
      });
    }));
  
    //2.
    beforeEach(function() {
  
  
      inject(function($injector) {
        service = $injector.get('ForumService');
        httpBackend = $injector.get('$httpBackend');
        $q = $injector.get('$q');
  
      });
  
    });
  
  
    // 5. make sure no expectations were missed in your tests.
    afterEach(function() {
      httpBackend.verifyNoOutstandingExpectation();
      httpBackend.verifyNoOutstandingRequest();
    });
  
  
    it('should use Function', function() {
  
  
      var returnData = [
  
        {
          id: 1,
          name: "Programming Questions",
          description: "Please post all Questions you have in regards to programming here"
        }, {
          id: 2,
          name: "OOP",
          description: "Object Oriented Programming"
        }
      ];
  
  
      console.info('foo');
      httpBackend.when('GET', 'localhost/api/forums').respond(200, returnData);
  
      service.getForums().then(function(response) {
        console.info(response); // to see the response
        expect(response.data.id).toBe(1);
        expect(response.data.name).toBe("Programming Questions");
        expect(response.data.description).toBe("Please post all Questions you have in regards to programming here");
      });
  
      httpBackend.flush();
  
  
    });
  
  });</code></pre>
  </div>
  </div>
  </p>
  
  <p>And this is my model class</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>(function() {
    'use strict';
  
    angular
      .module('app.models')
      .factory('Forum', Forum);
  
    Forum.$inject = [];
  
    function Forum() {
      /**
       * Forum prototype (constructor function).
       *
       * @param data
       * @constructor
       */
      function Forum(data) {
        var self = this;
  
        if (angular.isDefined(data)) {
          self.id = data.id;
          self.name = data.name;
          self.description = data.description;
        } else {
          self.id = 0;
          self.name = '';
          self.description = '';
        }
      }
  
      return Forum;
    }
  })();</code></pre>
  </div>
  </div>
  </p>