服务承诺不以业力解决

service promise not resolving with karma

本文关键字:解决 服务承诺      更新时间:2023-09-26

我有一个service factory,它连接数据并与之交互api。这是服务:

angular.module('dbRequest', [])
  .factory('Request', ['$http', 'localConfig', function($http, localConfig){
    return {
      getDataRevision: function(){
        return $http({
          url: localConfig.dbDataUrl,
          method: "GET",
          crossDomain: true,
          headers: {
            'Content-Type': 'application/json; charset=utf-8'
          }
        })
      }
    }
  }]);

从这个答案中得到线索,这就是我测试该方法的方式:

describe('Service: Request', function () {
  var $scope, srvMock, $q, lc, $httpBackend;
  beforeEach(module('webApp'));
  beforeEach(inject(function($rootScope, Request, _$q_, _$httpBackend_, localConfig){
    $scope = $rootScope.$new();
    srvMock = Request;
    $q = _$q_;
    $httpBackend = _$httpBackend_;
    lc = localConfig;
    $httpBackend.expect('GET', lc.dbDataUrl);
    $httpBackend.when('GET', lc.dbDataUrl).respond({
      success: ["d1","d2", "d3"]
    });
  }));
  it('should return a promise', function(){
    expect(srvMock.getDataRevision().then).toBeDefined();
  });
  it('should resolve with data', function(){
    var data;
    var deferred = $q.defer();
    var promise = deferred.promise;
    promise.then(function(res){
      data = res.success;
    });
    srvMock.getDataRevision().then(function(res){
      deferred.resolve(res);
    });
    $scope.$digest();
    expect(data).toEqual(["d1","d2", "d3"]);
  })
});

should return a promise通过,但下一个should resolve with data失败并显示此错误:

Expected undefined to equal [ 'd1', 'd2', 'd3' ].

但是,service方法getDataRevision被调用,但未被测试中的模拟承诺解决。如何进行更正?

目前,您希望模拟数据存在于变量data而不刷新httpRequest,但在您flush所有httpRequest之前,这不会发生。$httpBackend.flush()的作用是,它将模拟数据返回到您使用$httpBackend.when('GET', lc.dbDataUrl).respond执行的特定请求。

此外,您不需要创建额外的承诺,这将是开销。而不是自定义承诺,您可以利用服务功能返回承诺本身,如下所示。

法典

it('should resolve with data', function(){
    var data;
    srvMock.getDataRevision().then(function(res){
      data = res.success;
    });
    $scope.$digest();
    $httpBackend.flush(); //making sure mocked response has been return
    //after .then evaluation only below code will get called.
    expect(data).toEqual(["d1","d2", "d3"]);
})