【问题标题】:Spying on service that returns a promise监视返回承诺的服务
【发布时间】:2014-05-01 04:00:29
【问题描述】:

我有一个使用缓存检索数据并回退到 $http 的服务,我正在尝试使用 jasmine 间谍在控制器规范中模拟对服务的调用。但是,当我调用scope.$digest 时,正在调用实际的服务并进行 HTTP 调用。

我已尝试使用 [$rootScope|scope].[$apply|$digest]() 的所有组合,但我的 HTTP 调用仍在进行中。但是,如果我从我的间谍返回承诺以外的其他内容,例如字符串,我会收到一个错误,指出 then 未定义为函数,因此看起来间谍正在成功地存根函数?

茉莉花测试

beforeEach(inject(function ($controller, $rootScope) {
  scope = $rootScope.$new();

  // Should be called by each test after mocks and spies have been setup
  startContoller = function() {
    $controller('SearchCtrl', {
      $scope: scope,
      $stateParams: { q: 'test' }
    });
  };
}));

it('sets error message when no results', inject(function(QuestionService, $q) {
  var deferred;
  spyOn(QuestionService, 'search').and.callFake(function() {
    deferred = $q.defer();
    deferred.reject();
    return deferred.promise;
  });

  startContoller();
  scope.$digest();

  expect(scope.error).toBe(true);
}));

控制器

.controller('SearchCtrl', ['$scope', '$stateParams', 'QuestionService',
  function($scope, $stateParams, QuestionService) {
    var query = $stateParams.q;

    $scope.page = 1;
    QuestionService.search(query, $scope.page).then(function(questions) {
      if (questions.length === 0) {
        $scope.error = true;
        $scope.errorMessage = 'No Results';
      } else {
        $scope.questions = questions;
      }
    }, function() {
      $scope.error = true;
    });
  }]);

【问题讨论】:

  • 您是否也尝试过将模拟服务注入控制器?

标签: javascript angularjs jasmine


【解决方案1】:

dmahapatro 的评论是要走的路。

当您使用 $controller('SearchCtrl'...) 检索控制器时,您的服务在执行“it”块时已经实例化,因此对其进行监视没有任何效果。

您应该在 $controller 调用中注入模拟服务。 此外,不需要您的 startController() 函数,因为调用 $controller 将执行控制器的逻辑。

var QuestionServiceMock, deferred;
beforeEach(inject(function ($controller, $rootScope) {
  scope = $rootScope.$new();

  QuestionServiceMock = jasmine.createSpyObj('QuestionService', ['search']);
  QuestionServiceMock.search.andCallFake(function () {
    deferred = $q.defer();
    deferred.reject();
    return deferred.promise;
  });
  $controller('SearchCtrl', {
    $scope: scope,
    $stateParams: { q: 'test' },
    QuestionService: QuestionServiceMock
  });
}));

it('sets error message when no results', inject(function(QuestionService, $q) {
  scope.$apply();

  expect(scope.error).toBe(true);
}));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多