在Jasmine单元测试中未调用Angular $ http.get成功处理程序

时间:2017-02-08 19:14:20

标签: javascript angularjs unit-testing jasmine angular-promise

我有一个非常基本的工厂服务,我想进行单元测试。我在$rootScope.$digest()语句之前尝试了$rootScope.$apply()expect,并且在单元测试中根本没有调用成功或失败处理程序 - 在应用程序中它们被称为正常但是,使用这家工厂的控制器。

example.service.js:

(function (angular) {
  'use strict';

  angular
    .module('exampleModule')
    .factory('ExampleApi', ExampleApi);

  ExampleApi.$inject = ['$http'];
  function ExampleApi($http) {
    return {
      get: getExampleData
    }

    function getExampleData() {
      return $http.get('example-endpoint');
    }
  }

})(angular);

example.service.spec.js

'use strict';

describe('Example API service', function() {
  var $httpBackend;
  var $rootScope;
  var ExampleApi;

  beforeEach(module('exampleModule'));

  beforeEach(inject(
    function(_$httpBackend_, _$rootScope_, _ExampleApi_) {
      $httpBackend = _$httpBackend_;
      $rootScope = _$rootScope_;
      ExampleApi = _ExampleApi_;
  }));

  it('calls the success handler on success', function() {
    $httpBackend
      .expectGET('example-endpoint')
      .respond(200);

    var handlerStubs = {
      success: function() {
        console.log("success called");
      },
      failure: function() {
        console.log("failure called");
      }
    }

    spyOn(handlerStubs, 'success').and.callThrough();
    spyOn(handlerStubs, 'failure').and.callThrough();
    ExampleApi.get().then(handlerStubs.success, handlerStubs.failure);
    //$rootScope.$digest();
    $rootScope.$apply();
    expect(handlerStubs.failure.calls.count()).toEqual(0);
    expect(handlerStubs.success.calls.count()).toEqual(1);
  });
});

1 个答案:

答案 0 :(得分:1)

$httpBackend mock包含一个flush()方法,在调用时,它将解析get请求,使您可以同步控制被测代码。调用$httpBackend.flush();时,会验证期望.expectGET

From the Angular Docs:

  

生产中使用的$ httpBackend始终以异步方式响应请求。如果我们在单元测试中保留了这种行为,我们就必须创建难以编写的异步单元测试,以便跟踪和维护。但是测试模拟也不能同步响应;这会改变被测代码的执行。出于这个原因,模拟$ httpBackend有一个flush()方法,它允许测试显式刷新挂起的请求。这保留了后端的异步api,同时允许测试同步执行。