如何使用 jasmine 在指令中测试 'ng-click' 事件

how to test 'ng-click' event in directive with jasmine

我想用 jasmine 测试 angular 中的 'ng-click' 事件,但我不知道如何

我的指令文件是这样的(headbarDirective.js):

 (function () {
        angular.module('app.widgets.homeHeadbar',[])
            .directive('homeHeadbar', homeHeadbar);

        function homeHeadbar() {
            return {
                restrict: 'EAC',
                replace: true,
                transclude: false,
                scope: {
                    name: '@',
                    role: '@',
                },
                templateUrl: 'app/widgets/headbar/headbarView.html',
                link: function(scope, ele, attrs) {
                    if (!scope.name) {
                        scope.logined = false;
                    } else {
                        scope.logined = true;
                    }
                    scope.logout = function() {
                        UserService.logout();
                        $location.path('/login');
                };
                }
            };
        }
    })();

我的模板文件是这样的 (headbarView.html):

 <nav>
  <div>
    <div class="navbar-right" ng-show="logined">

      <div class="dib fr ml20">
         <div class="user-name cwh">{{name}}</div>
         <div class="user-position cgray">{{role}}</div>
      </div>

      <a class="logout" href="javascript:;" ng-click="logout()">Log Out</a>

    </div>
  </div>
</nav>

我的测试文件是这样的(test.js):

describe('test the headbarDirective',function(){

    beforeEach(module('templates','app','app.widgets.homeHeadbar'));

    var scope,ele,compile,simpleHtml,UserService,location;

    beforeEach(inject(function(_$rootScope_,_$compile_,_UserService_,_$location_){
        compile = _$compile_;
        scope = _$rootScope_.$new();
        location = _$location_;
        UserService = _UserService_;
    }));

    it('test the logout click',function(){
        simpleHtml = '<home-headbar name="John" role=2></home-headbar>';
        ele = compile(angular.element(simpleHtml))(scope);
        scope.$digest();

        spyOn(UserService,'logout').and.callThrough();

        $(ele).find('.logout').click();
        scope.$digest();

        expect(UserService.logout).toHaveBeenCalled();
    });
});

测试失败,控制台结果如下:

Chrome 43.0.2357 (Windows 7 0.0.0) test the headbarDirective test the logout cli
ck FAILED
        Expected spy logout to have been called.
            at Object.<anonymous> (C:/Users/IBM_ADMIN/desk/workspace/WaterFundWe
b/WebContent/test/unit/widgets/headbar/headbarDirective.js:48:30)
Chrome 43.0.2357 (Windows 7 0.0.0): Executed 11 of 11 (1 FAILED) (0 secs / 0.124
Chrome 43.0.2357 (Windows 7 0.0.0): Executed 11 of 11 (1 FAILED) (0.125 secs / 0
.124 secs)

表示还没有调用注销函数。 我的代码有问题吗?如何测试 ng-click 事件?

让我测试一下是否适合您,请随时"run code snippet"

angular.module('app.widgets.homeHeadbar', [])
  .directive('homeHeadbar', function homeHeadbar($location, UserService) {
    return {
      restrict: 'EAC',
      replace: true,
      transclude: false,
      scope: {
        name: '@',
        role: '@',
      },
      templateUrl: 'app/widgets/headbar/headbarView.html',
      link: function(scope, ele, attrs) {
        scope.logout = function() {
          UserService.logout();
          $location.path('/login');
        };
      }
    };
  });

describe('test the headbarDirective', function() {

  var scope, el, $compile, $location, simpleHtml, UserService;

  beforeEach(module('app.widgets.homeHeadbar'));

  /* stub as I don't know implementations for UserService */
  beforeEach(function() {
    var _stubUserService_ = {
      logout: jasmine.createSpy('UserService.logout')
    };

    angular.module('app.widgets.homeHeadbar')
      .value('UserService', _stubUserService_);
  });

  beforeEach(inject(function($rootScope, $templateCache, _$compile_, _$location_, _UserService_) {
    $templateCache.put('app/widgets/headbar/headbarView.html', [
      '<nav>',
      '  <div>',
      '    <div class="navbar-right" ng-show="logined">',
      '      <div class="dib fr ml20">',
      '        <div class="user-name cwh">{{name}}</div>',
      '        <div class="user-position cgray">{{role}}</div>',
      '      </div>',
      '      <a class="logout" href="javascript:;" ng-click="logout()">Log Out</a>',
      '    </div>',
      '  </div>',
      '</nav>'
    ].join(''));
    $location = _$location_;
    $compile = _$compile_;
    scope = $rootScope.$new();
    UserService = _UserService_;
  }));

  it('clicks on "logout" redirects to /login page', function() {
    spyOn($location, 'path')

    simpleHtml = '<home-headbar name="John" role=2></home-headbar>';
    el = $compile(angular.element(simpleHtml))(scope);
    scope.$digest();

    el.find('.logout').click();

    expect(UserService.logout).toHaveBeenCalled();
    expect($location.path).toHaveBeenCalledWith('/login');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />
<script src="//safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-mocks.js"></script>