监视返回承诺的服务

时间:2014-03-23 23:26:54

标签: javascript angularjs jasmine

我有一个服务,它使用缓存检索数据并回退到$ http,并且我试图使用jasmine spies在控制器规范中模拟对服务的调用。但是,当我调用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;
    });
  }]);

1 个答案:

答案 0 :(得分:0)

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