簡體   English   中英

如何在Jasmine的承諾下測試代碼,然后阻止?

[英]How to test code within then block following a promise with Jasmine?

我有下面的代碼,我想盡可能地對其進行測試。 我只是在摸索如何在authenticationService.authenticate()的then塊中測試這兩行。 我已經來回搜索,但是沒有找到任何可用的信息。

當我檢查廣播是否被觸發時,結果為假,因為最初有一條廣播消息觸發了整個代碼。

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'); 被調用-這是測試主題嗎?

測試promise的要點是要知道可以通過執行$rootScope.$digest()來解決promise。 另一點是模擬由返回承諾的特定函數返回的承諾(通過返回已解決的承諾或被拒絕的承諾)。 這樣,可以為您提供控制測試流程的工具。 以下測試向您展示了如何執行此操作:

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

    });

  });


});

您要測試promise行為還是僅測試成功回調中的邏輯?

如果只是回調,那么我將從匿名函數轉到其自己的函數,並在沒有承諾的情況下對其進行測試。

否則,我認為您可以在測試中使用$ httpBackend來觸發承諾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM