Comment puis-je Tester un .catch Promesse de Retour dans AngularJS à l'aide de Jasmin?

Je suis assez nouveau à Javascript et de l'apprentissage AngularJS, mais j'ai obtenu la plupart de mes cas de test à travailler avec quelques grands exemples que j'ai trouvé. Malheureusement, je n'arrive pas à trouver quelque chose pour m'aider à tester mon cas actuel.

Je me suis mise à l'essai d'un Contrôleur à l'aide d'un moqué de Service dont la méthode retourne une promesse. Je voudrais la moqué de Service renvoie une erreur, pour l'exécution de l' '.attraper " bloc de la méthode de contrôleur. Je peux dire qu'il n'est pas appelée correctement dans un couple des manières:

  1. Je suis en utilisant istanbul pour la couverture de code et il me dit que je ne suis pas couvrant les "attraper"
  2. Le code dans le".attraper " le bloc n'est pas exécuté à partir de ce que je peux dire par le débogage

Le contrôleur en vertu de test, spécialement besoin de tester le".attraper " dans $champ d'application.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;
        });
      }
    };
  });

Le service et la méthode, je suis d'essayer de se moquer:

Auth.connexion

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

Et enfin, mon fichier de test. Le plus drôle, c'est que tous les tests passent, mais le "prévoir" dans le dernier test peut être changé à peu près n'importe quoi et il continue de passer. Les deux premiers tests semblent fonctionner comme prévu, mais le dernier test est lorsque j'essaie d'exécuter le bloc catch en jetant une erreur de la simulation de service Auth:

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

Je m'excuse pour poster autant de code, mais je voulais fournir autant que possible. J'apprécie vraiment quelqu'un qui peut m'aider à m'en sortir comme je apprendre mon chemin autour de l'unité de test Angulaire et de promesses! Merci!!!

**Mise à JOUR**

J'ai pu résoudre mon problème avec l'aide de quelques ci-dessous et de découvrir quelques erreurs syntaxiques. Voici ce que fixe ce:

  1. Mon beforeEach sur le dernier test n'a pas été fermé correctement et réellement contenu du dernier essai, l'amenant à ne pas s'exécuter correctement (ou peut-être à tous). C'est pourquoi en changeant le fait de s'attendre a abouti à aucune erreur.
  2. J'ai changé mon beforeEach injecter: mockAuthService.login.andReturn($q.reject({data: {message: 'Bad Login!'}})); à l'aide de la reject indiqué ci-dessous.
  3. Une fois que j'ai bien fermé la beforeEach j'ai un message d'erreur que $q n'a pas été définis, j'ai donc ajouté ça à inject(function($q)

Une fois que j'ai corrigé ces problèmes, la promesse a été rejeté à juste titre et l'erreur a été capturé par le code approprié dans le contrôleur.

OriginalL'auteur sbrown | 2014-05-03