2014-05-03 18 views
8

Tôi khá mới với Javascript và chỉ học AngularJS nhưng tôi đã nhận được hầu hết các trường hợp thử nghiệm của mình để làm việc với một số ví dụ tuyệt vời mà tôi đã tìm thấy. Thật không may tôi dường như không thể tìm thấy bất cứ điều gì để giúp tôi kiểm tra trường hợp hiện tại của tôi.Làm thế nào tôi có thể kiểm tra một trả lời hứa hẹn .catch trong AngularJS sử dụng Jasmine?

Tôi đang thử nghiệm một Bộ điều khiển bằng cách sử dụng Dịch vụ được giả lập có phương thức trả về lời hứa. Tôi muốn dịch vụ giả lập trả về lỗi để thực thi khối '.catch' trong phương thức điều khiển. Tôi có thể nói rằng nó không nhận được gọi một cách chính xác trong một vài cách sau:

  1. Tôi đang sử dụng istanbul cho mã số bảo hiểm và nó nói với tôi Tôi không bao gồm các 'bắt'
  2. Mã trong ' .catch 'khối không nhận được thực hiện từ những gì tôi có thể nói qua gỡ lỗi

Bộ điều khiển dưới kiểm tra, đặc biệt cần phải kiểm tra' .catch' trong $ 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; 
     }); 
     } 
    }; 
    }); 

Các dịch vụ và phương pháp Tôi đang cố gắng để chế nhạo:

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

Và cuối cùng, tập tin thử nghiệm của tôi. Phần buồn cười là tất cả các bài kiểm tra đều đi qua nhưng 'kỳ vọng' trong bài kiểm tra cuối cùng có thể được thay đổi thành khá nhiều thứ và nó vẫn trôi qua. Hai bài kiểm tra đầu tiên dường như chạy như mong đợi nhưng các thử nghiệm cuối cùng là nơi tôi đang cố gắng để thực hiện khối catch bằng cách ném một lỗi từ dịch vụ Auth giả:

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

    }); 
    }); 
}); 

Tôi xin lỗi vì đã đăng nhiều mã nhưng tôi muốn cung cấp nhiều bối cảnh nhất có thể. Tôi thực sự đánh giá cao bất cứ ai có thể giúp tôi khi tôi học theo cách của tôi xung quanh thử nghiệm đơn vị Góc cạnh và hứa hẹn! Cảm ơn!!!

** CẬP NHẬT **

tôi đã có thể giải quyết vấn đề của tôi với một số sự giúp đỡ từ bên dưới và phát hiện một số lỗi cú pháp. Dưới đây là những gì đã khắc phục sự cố này:

  1. beforeEach trong thử nghiệm cuối cùng không được đóng đúng và thực sự kèm theo thử nghiệm cuối cùng khiến nó không chạy đúng (hoặc có thể). Đây là lý do tại sao thay đổi điều kiện mong đợi dẫn đến không có lỗi.
  2. Tôi đã thay đổi số beforeEach tiêm của mình thành: mockAuthService.login.andReturn($q.reject({data: {message: 'Bad Login!'}})); bằng cách sử dụng reject được đề xuất bên dưới.
  3. Khi tôi đúng đóng beforeEach tôi nhận được một thông báo lỗi rằng $ q không được định nghĩa vì vậy tôi đã phải thêm nó vào inject(function($q)

Khi tôi sửa chữa những vấn đề này lời hứa đã bị từ chối một cách chính xác và lỗi đã bị bắt bởi mã thích hợp trong bộ điều khiển.

Trả lời

8

Trước hoặc trong khi chạy thử nghiệm của bạn, thử ra một phần của môi trường như thế này:

var originalAuthLogin = Auth.login; 
Auth.login = function() { 
    return Promise.reject({data: {message: 'Error message'}}); 
}; 

Sau khi thử nghiệm phục hồi môi trường để sự tỉnh táo:

Auth.login = originalAuthLogin; 

này ngay lập tức gọi .catch() khối mã bạn đang cố kiểm tra.

+1

Dan, cảm ơn sự giúp đỡ! Tôi có nên đánh dấu câu trả lời của bạn như là giải pháp thậm chí nghĩ rằng tôi đã không sử dụng nó chính xác như được đăng? Nó chắc chắn chỉ cho tôi đi đúng hướng. – sbrown

+1

chắc chắn, bạn có thể đánh dấu nó như là một giải pháp nếu nó cố định vấn đề của bạn ... không quan trọng nhiều với tôi một trong hai cách. –

+0

Trong trường hợp của tôi, tôi không thể sử dụng Promise.reject – svassr

Các vấn đề liên quan