2015-07-19 29 views
1

我有下面的代碼,我想盡可能多地測試它。我只是在摸索着如何在authenticationService.authenticate()的當時塊內測試這兩條線。我已經來回搜索,但我還沒有找到任何可用的信息。如何在茉莉花承諾之後測試代碼中的代碼?

當我檢查廣播是否被觸發時,結果是錯誤的,因爲最初有廣播消息觸發整個代碼。

function shellController($location, $rootScope, $scope, authenticationService, authService, common) 
    { 
     $scope.$on('event:auth-loginRequired', function() 
     { 

      var user = { 
       userName: 'visitor', 
       password: 'visitor' 
      }; 

      authenticationService.authenticate(user).then(function (result) { 

       $rootScope.$broadcast('event:username-changed'); 

       authService.loginConfirmed(); 
      }); 

     }); 
    } 

我如何可以模擬當authenticationService.authenticate()成功返回 - 它不是測試對象是否成功與否返回 - 而$rootScope.$broadcast('event:username-changed');是否被調用 - 這是測試對象?

+0

你只是想確認是否'事件:用戶名 - change'事件有被廣播和authService.loginConfirmed()被調用? – ryeballar

+0

是的。那是對的! – SayusiAndo

回答

1

測試承諾的要點是要知道承諾可以通過執行$rootScope.$digest()來解決或拒絕。另一點是嘲笑由返回承諾的特定函數返回的承諾(通過返回已解決的承諾或被拒絕的承諾)。通過這樣做,爲您提供控制測試流程的設施。下面的測試顯示你如何做到這一點:

DEMO

script.spec.js

describe('shellController', function() { 

    var locals, 
     shellController, 
     $q; 

    beforeEach(module('app')); 

    beforeEach(inject(function($controller, $location, $rootScope, _$q_) { 

    $q = _$q_; 

    locals = { 
     $location: $location, 
     $rootScope: $rootScope, 
     $scope: $rootScope.$new(), 
     authenticationService: { 
     authenticate: jasmine.createSpy('authenticate') 
     }, 
     authService: { 
     loginConfirmed: jasmine.createSpy('loginConfirmed') 
     }, 
     common: {} 
    }; 

    shellController = $controller('shellController', locals); 

    })); 

    describe('event:auth-loginRequired', function() { 

    it('should authenticate user', function() { 

     locals.authenticationService.authenticate.and.returnValue($q.when()); 
     locals.$rootScope.$broadcast('event:auth-loginRequired'); 

     expect(locals.authenticationService.authenticate).toHaveBeenCalledWith({ 
     userName: 'visitor', 
     password: 'visitor' 
     }); 

    }); 

    describe('when user authentication succeeds', function() { 

     var spy, 
      result; 

     beforeEach(function() { 

     result = {}; 
     locals.authenticationService.authenticate.and.returnValue($q.when(result)); 

     spy = jasmine.createSpy('event:username-changed'); 
     locals.$scope.$on('event:username-changed', spy); 

     locals.$rootScope.$broadcast('event:auth-loginRequired'); 
     locals.$rootScope.$digest(); 

     }); 

     it('should broadcast an event `event:username-changed` to all scopes', function() { 
     expect(spy).toHaveBeenCalled(); 
     }); 

     it('should call authService.loginConfirmed()', function() { 
     expect(locals.authService.loginConfirmed).toHaveBeenCalled(); 
     }); 

    }); 

    describe('when user authentication fails', function() { 

     var spy; 

     beforeEach(function() { 
     locals.authenticationService.authenticate.and.returnValue($q.reject()); 

     spy = jasmine.createSpy('event:username-changed'); 
     locals.$scope.$on('event:username-changed', spy); 

     locals.$rootScope.$broadcast('event:auth-loginRequired'); 
     locals.$rootScope.$digest(); 

     }); 

     it('should not broadcast an event `event:username-changed` to all scopes', function() { 
     expect(spy).not.toHaveBeenCalled(); 
     }); 

     it('should not call authService.loginConfirmed()', function() { 
     expect(locals.authService.loginConfirmed).not.toHaveBeenCalled(); 
     }); 

    }); 

    }); 


}); 
+0

男人,這太棒了!非常感謝你!你幫了我很多,不僅僅是回答這個問題,還有整個測試的東西。再次感謝! – SayusiAndo

0

您想要測試承諾行爲還是隻測試成功回調中的邏輯?

如果它只是回調,那麼我會從一個匿名函數轉移到它自己的函數,並在沒有承諾的情況下測試它。

否則我認爲你可以在你的測試中使用$ httpBackend來觸發諾言。

+0

我想測試成功回調中的邏輯。不過,我把這個問題改寫了一下,因爲它不夠清楚。 – SayusiAndo