Как написать тест кармы для обещания

0

У меня есть код, который запускает таймер, когда пользователь активен, а также трансляции и события, чтобы сохранить сеанс.

В контроллере у меня есть код для прослушивания этого события и обновления сеанса.

Я хочу протестировать этого слушателя

$scope.$on('Keepalive', function () {
   //every 45 minutes make a call to refresh the session.
   var promise = authService.keepAliveSession();
   promise.then(function(userPreferenceData) {
      dataTransfer.setUserPref(userPreferenceData);
   }, function(error) {
      console.log("promise error!!"+error);
   });      
 });

мой сервис keepalive возвращает обещание, которое будет разрешено после возврата httpbackend.

factory.keepAliveSession = function () {

  var deferred = $q.defer();

  req=...some stuff...

  $http(req)
    .success(
       function (data, status) {
          if ( data.user ) {
            // Received data about the logged in user 
             deferred.resolve(factory.userPreferenceData);
          } else {
              // User is not authenticated; redirect to login
              $window.location = data.redirect;
           }
       }
    ).error(function (error) {
        // Error in oAuth refresh service
        deferred.reject("Error in session keepalive"+ error);
    });

    return deferred.promise; 
}

вот тест

it('Test for keepalive', function() {
            console.log('starting for keepalive...');
            httpBackend.when('POST', "http://example.com/refreshSession").respond(getMocks().response.oAuthResponseExternal);

            spyOn(authServiceMock, "keepAliveSession").and.callThrough();
            spyOn(dataTransferMock, "setUserPref").and.callThrough();

            rootScope.$broadcast('Keepalive');

            expect(authServiceMock.keepAliveSession).toHaveBeenCalled();
            rootScope.$digest;
            expect(dataTransferMock.setUserPref).toHaveBeenCalled();

        });

Первое утверждение является успешным, но второе (после дайджеста) терпит неудачу.

Как я могу заставить обещание быть разрешенным или отвергнутым? Нужно ли мне как-то издеваться над $ q?

  • 0
    Это сработало для вас?
Теги:
karma-jasmine

1 ответ

1

Трудно сказать наверняка, не видя притворных реализаций, как вы подключаете модуль и как вы создаете контроллер.

Я предполагаю, что обещание, которое возвращается из authServiceMock.keepAliveSession никогда не будет разрешено, что приведет к тому, что функция успеха, которую обеспечивает dataTransfer.setUserPref никогда не будет выполнена.

Если вы, например, имеете макет, который выглядит так:

var deferred;

var authServiceMock = {

  keepAliveSession: function () {

    deferred = q.defer();

    return deferred.promise;
  }
};

Вам необходимо вручную выполнить тест или разрешить или отклонить обещание перед запуском цикла дайджеста, в зависимости от того, в каком случае вы тестируете:

expect(authServiceMock.keepAliveSession).toHaveBeenCalled();

deferred.resolve('something');
$rootScope.$digest();

expect(dataTransferMock.setUserPref).toHaveBeenCalled();

Обратите внимание, что вам нужно выполнить функцию $digest, в вашем примере у вас есть rootScope.$digest; ,


На другой ноте, мне кажется, вы немного смешаете проблемы тестирования.

С моей точки зрения, это то, что должен проверить ваш контроллер:

  1. Когда событие Keepalive уволено - authService.keepAliveSession следует называть
  2. Если обещание authService.keepAliveSession разрешено - необходимо вызвать dataTransfer.setUserPref и передать правильные данные
  3. Если authService.keepAliveSession от authService.keepAliveSession отклонен - сообщение об ошибке должно быть зарегистрировано

Детали реализации служб не должны иметь значения (кроме того, что authService.keepAliveSession возвращает обещание), и в этом случае вам не нужно привлекать httpBackend.

Настройка поддельных данных возврата с помощью httpBackend следует использовать при проверке фактической службы, использующей службу $http.

Ниже приведен альтернативный способ проверить это, используя spyOn и callFake вместо использования макетных реализаций.

describe('myApp', function() {

  var $rootScope;
  var $controller;
  var authService;
  var dataTransfer;
  var $log;
  var myController;

  beforeEach(function() {

    module('myApp');

    inject(function(_$rootScope_, _$controller_, _authService_, _dataTransfer_, _$q_, _$log_) {

      $rootScope = _$rootScope_;
      $controller = _$controller_;
      authService = _authService_;
      dataTransfer = _dataTransfer_;
      $q = _$q_;
      $log = _$log_;
    });

    myController = $controller('MyController', {
      $scope: $rootScope.$new()
    });
  });

  it('On event "Keepalive" - should call "authService.keepAliveSession"', function() {

    spyOn(authService, 'keepAliveSession').and.callFake(function() {

      var deferred = $q.defer();
      return deferred.promise;
    });

    $rootScope.$broadcast('Keepalive');

    expect(authService.keepAliveSession).toHaveBeenCalled();
  });

  it('Promise from "authService.keepAliveSession" is resolved - should call "dataTransfer.setUserPref"', function() {

    var data = {};

    spyOn(authService, 'keepAliveSession').and.callFake(function() {

      var deferred = $q.defer();
      deferred.resolve(data);
      return deferred.promise;
    });

    spyOn(dataTransfer, 'setUserPref');

    $rootScope.$broadcast('Keepalive');

    $rootScope.$digest();

    expect(dataTransfer.setUserPref).toHaveBeenCalledWith(data);
  });

  it('Promise from "authService.keepAliveSession" is rejected - should not call "dataTransfer.setUserPref"', function() {

    var data = {};

    spyOn(authService, 'keepAliveSession').and.callFake(function() {

      var deferred = $q.defer();
      deferred.reject(data);
      return deferred.promise;
    });

    spyOn(dataTransfer, 'setUserPref');

    $rootScope.$broadcast('Keepalive');

    $rootScope.$digest();

    expect(dataTransfer.setUserPref).not.toHaveBeenCalled();
  });

  it('Promise from "authService.keepAliveSession" is rejected - should log message', function() {

    var error = {};

    spyOn(authService, 'keepAliveSession').and.callFake(function() {

      var deferred = $q.defer();
      deferred.reject(error);
      return deferred.promise;
    });

    spyOn($log, 'log');

    $rootScope.$broadcast('Keepalive');

    $rootScope.$digest();

    expect($log.log).toHaveBeenCalledWith(error);
  });
});

Демо: http://plnkr.co/edit/L1uks0skH2N5bAXGoe90?p=preview

Ещё вопросы

Сообщество Overcoder
Наверх
Меню