【问题标题】:Angular $http.get success handler not called in Jasmine unit testJasmine 单元测试中未调用 Angular $http.get 成功处理程序
【发布时间】:2017-06-26 13:53:30
【问题描述】:

我有一个非常基本的工厂服务,我想对其进行单元测试。我在expect 语句之前尝试了$rootScope.$digest()$rootScope.$apply(),并且在单元测试中根本没有调用成功或失败处理程序 - 在使用该工厂的控制器的上下文中,它们在应用程序中被调用得很好,不过。

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);
  });
});

【问题讨论】:

  • response(200);之后尝试$httpBackend.flush();
  • @LukeHutton 它在response(200) 之后没有工作,但在ExampleApi.get() 语句之后它确实有效。如果您将其写为答案,我会将其标记为正确答案。非常感谢! (在response 行之后,它说Error: No pending request to flush ! 这就是为什么我想在get() 之后尝试它。)

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


【解决方案1】:

$httpBackend mock 包含一个flush() 方法,当调用该方法时,将解析获取请求,让您同步控制被测代码。当$httpBackend.flush();被调用时,期望.expectGET得到验证。

From the Angular Docs:

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

【讨论】:

    猜你喜欢
    • 2016-10-08
    • 2021-09-25
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多