javascript - 如何在 Jasmine 的 promise 之后测试 then block 中的代码?

标签 javascript angularjs unit-testing jasmine

我有下面的代码,我想尽可能地测试它。我只是摸不着头脑如何测试authenticationService.authenticate() 的then block 中的这两行。我翻来覆去,没有找到任何有用的信息。

当我检查广播是否被触发时,结果是错误的,因为原来有一条广播消息触发了整个代码。

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 的要点是要知道 Promise 可以通过执行 $rootScope.$digest() 来解决或拒绝。 。另一点是模拟返回 Promise 的特定函数返回的 Promise(通过返回已解决的 Promise 或拒绝的 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();
      });

    });

  });


});

关于javascript - 如何在 Jasmine 的 promise 之后测试 then block 中的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31501496/

相关文章:

AngularJS Controller 和 "use strict"

javascript - 通过 AngularJS 停用元素

unit-testing - 禁用 grails 命令对象中的验证约束以进行单元测试(使用 Spock)

javascript - 如何评估第一个快照

vb.net - 在 VB.Net 中使用最小起订量的经验

javascript - 使用 jquery 计算 upwork 等付款的百分比

javascript - 如果选中 radio ,则禁用选择表单

javascript - Node.js Express - 在代理请求后调用 next()

javascript - HTML 闪烁文字颜色

javascript - Angular JS : HTML in $scope throws jshint error?