title: Unit Testing angular $httpBackend service
body: <p>I've got right now a project were we need to have the backend server mocked for the time being and we are using <code>$httpBackend</code> on the application <code>.run</code> feature.  I need to unit test this service that contains the <code>$httpBackend</code> as we will be having a vast amount of mocked calls to the server we will be covering. So right now this is what I have.  As a preface to my question the current setup works when I call <code>mockDataService.getWorkflowTask</code> from a controller on a simple page.</p>
  
  <p>My Server replacement service:</p>
  
  <pre><code>angular.module('app').run(function ($httpBackend, $resource, FakeBackendService) {
      // TODO: add all necessary http intercepts.  
      $httpBackend.whenGET('JSON file').respond(function (method, url, data) {
          var request = new XMLHttpRequest();
          request.open('GET', url, false);
          request.send(null);
          return [request.status, request.response, {}];
      });
      $httpBackend.whenGET(/.*/).respond(function (method, url, data) {
  
          return [200, FakeBackendService.getWorkflowTasks(), {}];
      });
  });
  </code></pre>
  
  <p>Here is the service for <code>FakeBackendService</code>:</p>
  
  <pre><code>(function () {
      'use strict';
  
      var injectParams = [];
  
      function service(lodash) {
          var vm = this;
  
          var ret = {
              getWorkflowTasks: getWorkflowTasks
          };
  
          function getWorkflowTasks() {
              if (vm.workflowtasks.length &lt; 1) {
                  vm.workflowtasks = loadWorkflowTasks("Some JSON file");
              }
              return vm.workflowtasks;
          };
  
          function loadWorkflowTasks(file) {
              var workflowTasks = [];
              var request = new XMLHttpRequest();
              request.open("GET", file, false);
              request.send(null);
  
              if (request.status == 200) {
                  workflowTasks = angular.fromJson(request.response);
              }
              return workflowTasks;
          };
  
          function init() {
              vm.workflowtasks = [];
          }
  
          init();
  
          return ret;
      }
  
      service.$inject = injectParams;
      angular.module('mock.FakeBackendService', []).service('FakeBackendService', service);
  })();
  </code></pre>
  
  <p>So that is currently the backend server replacement mock. The following is my data handling service which contains the call to <code>$http.get(blah blah blah)</code>.</p>
  
  <pre><code>(function () {
      'use strict';
  
      var injectParams = ['$http', '$q', 'mockConfigService', '$httpBackend'];
  
      function factory($http, $q, configService, $httpBackend) {
          var vm = this;
  
          var factory = {
              getWorkflowTask: getWorkflowTask
          };
  
          function getWorkflowTask(str) {
              return getResource(str);
          }
  
          function init() {
              // Get the URL we will be using to get data from
              vm.dataServiceURL = configService.getDataServiceURL();
          }
  
          function getResource(baseResource) {
              var resource = vm.dataServiceURL + baseResource;
  
              return $http.get(resource).then(function (response) {
                  if (typeof response.data == 'object') {
                      // Got valid response
                      return $q.resolve(response.data);
                  }
                  else {
                      // Invalid response
                      return $q.reject(response.data);
                  }
              }, function (response) {
                  // Something went wrong
                  return $q.reject(response.data);
              });
          }
          init();
  
          return factory;
      };
  
      factory.$inject = injectParams;
  
      angular.module('mock.dataService', []).factory('mockDataService', factory);
  }());
  </code></pre>
  
  <p>Now for the Jasmine-Karma Unit test.</p>
  
  <pre><code>describe("HTTP Backend Mock testing", function () {
  
      beforeEach(angular.mock.module("app"));
      beforeEach(angular.mock.module("mock.FakeBackendService"));
      beforeEach(angular.mock.module("mock.configService"));
      beforeEach(angular.mock.module("mock.dataService"));
  
      it("Get the workflow task", angular.mock.inject(function (mockDataService) {
          var valid = "";
  
          var promise = mockDataService.getWorkflowTask('http://localhost/foo');
  
          promise.then(function (response) {
              valid = "Success";
          }, function (response) {
              valid = "Failure";
          });
  
          expect(valid).toBe("Success");
      }));
  });
  </code></pre>
  
  <p>Now to the question.  So, I'll start by saying I'm new to the AngularJS world and even more so to Jasmine.  Anyways, when I debug the unit test I find that the promise's status is still 0 and I always get expected '' to be 'Success' telling my I never resolve (hopefully I'm using the right lingo) the promise from the <code>$http</code> service in <code>mockDataService</code>.  I've tried playing around with it some and tried to see if anyone has done this kind of a thing before.  I found plenty of examples where the <code>$httpBackend</code> is mocked in the test but none like what I'm attempting.  Any ideas or suggestions would be great.  Thanks.</p>
  
  <p><strong>EDIT got a slightly working solution</strong></p>
  
  <p>So I decided that I'd by pass the <code>run()</code> service and just do the same response in the <code>expectGET().respond()</code>.</p>
  
  <pre><code>describe("HTTP Backend Mock testing", function () {
      beforeEach(angular.mock.module("app"));
      beforeEach(angular.mock.module("mock.FakeBackendService"));
      beforeEach(angular.mock.module("mock.configService"));
      beforeEach(angular.mock.module("mock.dataService"));
  
      it("Get the workflow task", angular.mock.inject(function (mockDataService, $httpBackend, FakeBackendService) {
          var valid = "";
          $httpBackend.expectGET('http://server:80/api/foo').respond(200, FakeBackendService.getWorkflowTasks());
          var promise = mockDataService.getWorkflowTask('foo');
  
  
          promise.then(function (response) {
              valid = "Success";
          }, function (response) {
              valid = "Failure";
          });
          $httpBackend.flush();
  
          expect(valid).toBe("Success");
      }));
  });
  </code></pre>
  
  <p>This sort of solves my testing problem with the <code>run()</code> as the goal was to verify <strong>1)</strong> That the regex matching call the correct <code>FakeBackendService</code> and <strong>2)</strong> That <code>FakeBackendService</code> returns correct file and actually loads it.  I think I can do that by mimicking the same regex in the <code>expectGET</code>.  However, I'll leave open for a bit to see if anyone knows how to get the <code>run()</code> to work. </p>