Wie Kann ich Testen .fangen Versprechen Zurück in AngularJS mithilfe von Jasmin?

Ich bin Recht neu in Javascript und nur zu lernen, AngularJS, aber ich habe die meisten meiner test-Fällen zu arbeiten mit einigen großen Beispiele, die ich gefunden habe. Leider kann ich nicht scheinen, nichts zu finden, mir zu helfen, testen Sie meinen aktuellen Fall.

Teste ich einen Controller mit einem verspottet Service dessen Methode gibt ein Versprechen. Ich möchte, dass das verspottet-Dienst einen Fehler zurück, um zu führen '.catch' - block in der controller-Methode. Ich kann sagen, dass es nicht immer ordnungsgemäß aufgerufen, in ein paar Möglichkeiten:

  1. Ich bin mit istanbul für code coverage und es sagt mir ich bin nicht für die "catch'
  2. Sie den code in der '.catch' - block nicht immer ausgeführt was ich sagen kann über die debugging -

Den controller im test, speziell für den test brauchen die '.Fang' in $scope.login:

login.js

'use strict';

angular.module('ibcwebDashApp')
  .controller('LoginCtrl', function ($scope, Auth, $location) {
    $scope.user = {};
    $scope.errors = {};

    $scope.login = function(form) {
      $scope.submitted = true;

      if(form.$valid) {
        Auth.login({
          email: $scope.user.email,
          password: $scope.user.password
        })
        .then( function() {
          //Logged in, redirect to home
          $location.path('/');
        })
        .catch( function(err) {
          err = err.data;
          $scope.errors.other = err.message;
        });
      }
    };
  });

Dem service und der Methode, die ich bin versucht zu spotten:

Auth.login

'use strict';

angular.module('ibcwebDashApp')
  .factory('Auth', function Auth($location, $rootScope, Session, User, $cookieStore) {

    //Get currentUser from cookie
    $rootScope.currentUser = $cookieStore.get('user') || null;
    $cookieStore.remove('user');

    return {

      /**
       * Authenticate user
       * 
       * @param  {Object}   user     - login info
       * @param  {Function} callback - optional
       * @return {Promise}            
       */
      login: function(user, callback) {
        var cb = callback || angular.noop;

        return Session.save({
          email: user.email,
          password: user.password
        }, function(user) {
          $rootScope.currentUser = user;
          return cb();
        }, function(err) {
          return cb(err);
        }).$promise;
      },

Und schließlich, meine test-Datei. Das lustige ist, dass alle Prüfungen sind vorbei, aber das "erwartet" in der letzten Prüfung geändert werden kann, um so ziemlich alles, und es immer noch geht. Die ersten beiden tests scheinen zu laufen wie erwartet, aber der Letzte test ist, wo ich versuche, führen Sie die catch-block wirft einen Fehler aus den mock-Auth-service:

login.unit.js

'use strict';

describe('Controller: LoginCtrl', function () {
  var $scope, $location, loginCtrl, mockAuthService;


  beforeEach(function() {
    mockAuthService = jasmine.createSpyObj('Auth', ['login']);

    module('ibcwebDashApp');

    module(function($provide) {
      $provide.value('Auth', mockAuthService);
    });

    inject(function($rootScope, $controller, $q, _$location_) {
      //create an empty scope
      $scope = $rootScope.$new();
      $location = _$location_;
      //declare the controller and inject our empty scope
      loginCtrl = $controller('LoginCtrl', {$scope: $scope, Auth: mockAuthService});

    });

  });


  describe('successful login', function() {

    beforeEach(function() {
      inject(function($q) {
        mockAuthService.login.andReturn($q.when());
      });

    });

    it('should call auth.login with the scope email and password when form is valid', function() {
      //given
      $scope.form = {};
      $scope.form.$valid = true;
      $scope.user.email = '[email protected]';
      $scope.user.password = 'password123';

      //when
      $scope.login($scope.form);

      //then
      expect($scope.submitted).toBe(true);
      expect(mockAuthService.login).toHaveBeenCalledWith({email:'[email protected]', password:'password123'});

      $scope.$apply(); //force return of auth.login promise

      expect($location.path()).toBe('/');
    });

    it('should not call auth.login if form is invalid', function() {
      //given
      $scope.form = {};
      $scope.form.$valid = false;

      //when
      $scope.login($scope.form);

      expect(mockAuthService.login).not.toHaveBeenCalled();
    });
  });

  describe('unsuccessful login', function() {

    beforeEach(function () {
      inject(function () {
        mockAuthService.login.andReturn($q.when(new Error('Bad Login!')));
      });

      it('should set errors.other to the returned auth error message', function() {
        //given
        $scope.form = {};
        $scope.form.$valid = true;

        //when
        $scope.login($scope.form);

        $scope.$apply();

        //then
        expect($scope.errors.other).toEqual('Bad Login!');
      });

    });
  });
});

Ich entschuldige mich für die Buchung so viel code, aber ich wollte so viel Kontext wie möglich. Ich wirklich zu schätzen, wer kann mir helfen, wie ich lernen, meinen Weg in unit-testing, Winkel-und Versprechungen! Danke!!!

**UPDATE**

Konnte ich lösen mein Problem mit etwas Hilfe von unten und entdecken einige syntaktische Fehler. Hier ist, was behoben:

  1. Meine beforeEach auf der letzten Prüfung wurde nicht richtig geschlossen und tatsächlich eingeschlossen der Letzte test, dass es nicht richtig läuft (oder vielleicht überhaupt). Dies ist der Grund, warum die änderung der Bedingungen erwarten ergab keine Fehler.
  2. Ich änderte meine beforeEach Spritzen: mockAuthService.login.andReturn($q.reject({data: {message: 'Bad Login!'}})); mit der reject unten vorgeschlagen.
  3. Einmal habe ich richtig geschlossen, die beforeEach bekam ich eine Fehlermeldung, dass $q wurde nicht definiert, also musste ich fügte hinzu, es zu inject(function($q)

Einmal korrigiert habe ich diese Probleme das Versprechen wurde korrekt abgelehnt und der Fehler war gefangen von den entsprechenden code in den controller.

InformationsquelleAutor sbrown | 2014-05-03
Schreibe einen Kommentar