Using ngMock to simulate $http calls in service unit tests

六眼飞鱼酱① 提交于 2019-12-03 16:44:13

Your suspected solution was on the right track - promises were the key to fixing the errors/failing tests.

Using your original $http service to conditionally return the factory object didn't work because you were effectively returning nothing from your factory function (due to the asynchronous promise resolution of $http).

I considered just putting return in front of your original $http.get() call. But that isn't the desired behavior, because the AngularJS .factory method should return a service object that you define, not an mere promise returned by the call to $http.

The solution is exposing a method on your exampleService object that can be called by your app. That getData() method returns a promise (via $http) which your app/test can handle asynchronously using .success() or .error()

./app/js/services/services.js

'use strict';
angular.module('myApp.services', [])
    .factory("exampleService", function ($http) {
        return {
            getData: function () {
                return $http.get("/exampleUrl");
            }
        }
  });

./test/unit/servicesSpec.js

'use strict';
describe('service', function() {
  var $httpBackend;

  beforeEach(module('myApp.services'));

  beforeEach(inject(function ($injector) {
    $httpBackend = $injector.get("$httpBackend");
    $httpBackend.when("GET", "/exampleUrl")
        .respond(200, {value:"goodValue"});
  }));

  afterEach(function () {
    $httpBackend.flush()
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  describe('exampleService successful http request', function () {
    it('.value should be "goodValue"', inject(function (exampleService) {

        exampleService.getData().success(function(response) {
          expect(response.value).toEqual("goodValue");
        }).error( function(response) {
          //should not error with $httpBackend interceptor 200 status
          expect(false).toEqual(true);
        });

    }));
  });


});

Note that Destron's comment about $httpBackend.flush() was also important to get the mock backend to intercept the $http.get() request from your service.

Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!