2016-06-03 6 views
0

Ich habe Code, der einen Timer ausführt, wenn Benutzer aktiv ist und sendet und Ereignis, um die Sitzung am Leben zu halten.Wie schreibe ich einen Karma-Test für ein Versprechen

In der Steuerung habe ich etwas Code, um auf dieses Ereignis zu hören und die Sitzung zu aktualisieren.

Ich mag diesen Zuhörer testen

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

mein Keep-Alive-Dienst ein Versprechen gibt, die nach dem httpbackend kehrt aufgelöst werden erhalten.

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

hier ist der Test

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

     }); 

Die erste Behauptung ist erfolgreich, aber die zweite (nach dem Digest) ausfällt.

Wie kann ich das Versprechen erzwingen, gelöst oder abgelehnt zu werden? Muss ich irgendwie das $ q verspotten?

+0

Hat diese Arbeit für Sie? – tasseKATT

Antwort

0

Es ist schwer zu sagen, ohne die Mock-Implementierungen zu sehen, wie Sie das Modul verdrahten und wie Sie den Controller erstellen.

Meine Vermutung ist, dass das Versprechen, das von zurückgegeben wird, nie gelöst wird, was dazu führen würde, dass die Erfolgsfunktion, die dataTransfer.setUserPref lebt nie ausgeführt wird.

Wenn Sie zum Beispiel ein Modell hat, die wie folgt aussieht:

var deferred; 

var authServiceMock = { 

    keepAliveSession: function() { 

    deferred = q.defer(); 

    return deferred.promise; 
    } 
}; 

Sie müssen in Ihrem Test manuell entweder auflösen oder das Versprechen ablehnen, bevor Sie den Digest Zyklus auslösen, je nachdem, welchem ​​Fall, dass Sie Tests sind :

expect(authServiceMock.keepAliveSession).toHaveBeenCalled(); 

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

expect(dataTransferMock.setUserPref).toHaveBeenCalled(); 

Beachten Sie, dass die $digest Funktion, in Ihrem Beispiel ausführen müssen, müssen Sie nur noch rootScope.$digest;.


Auf einer anderen Anmerkung, scheint es mir, Sie testen Mischen sind betrifft ein bisschen.

Aus meiner Sicht ist es das, was sollte Ihr Controller testen:

  1. Wenn das Keepalive Ereignis ausgelöst wird - dataTransfer.setUserPref sollte aufgerufen werden - authService.keepAliveSession sollte
  2. Wenn das Versprechen von authService.keepAliveSession aufgelöst wird aufgerufen werden und übergeben Sie die korrekten Daten
  3. Wenn das Versprechen von authService.keepAliveSession abgelehnt wird - eine Fehlermeldung
protokolliert werden soll

Die Implementierungsdetails der Dienste sollten keine Rolle spielen (abgesehen davon, dass authService.keepAliveSession ein Versprechen zurückgibt) und Sie sollten in diesem Fall nicht httpBackend einbeziehen müssen.

Das Einrichten falscher Rückgabedaten mit httpBackend sollte verwendet werden, wenn Sie den tatsächlichen Dienst testen, der den Dienst $http verwendet.

Unten ist eine alternative Möglichkeit, dies zu testen, mit spyOn und callFake statt Mock-Implementierungen zu verwenden.

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

Demo:http://plnkr.co/edit/L1uks0skH2N5bAXGoe90?p=preview

Verwandte Themen