Mocha测试套件中AngularJS指令的触发点击事件

Mocha测试套件中AngularJS指令的触发点击事件,angularjs,angularjs-scope,mocha.js,dom-events,jqlite,Angularjs,Angularjs Scope,Mocha.js,Dom Events,Jqlite,我有一个带有指令的常规angular应用程序。此指令包含一个具有ng click=“clickFunction()”调用的元素。当我单击该元素时,所有这些都可以正常工作。我现在需要为这个点击编写一个测试,确保这个函数在点击元素时实际运行——这就是我遇到的问题 下面是一个JSFIDLE来说明我的问题: 控制器包含一个函数clickFunction(),应在单击时调用该函数。单元测试应该模拟对指令元素的点击,从而触发对该函数的调用 clickFunction是用sinonjs模拟的,这样我就可以检查

我有一个带有指令的常规angular应用程序。此指令包含一个具有
ng click=“clickFunction()”
调用的元素。当我单击该元素时,所有这些都可以正常工作。我现在需要为这个点击编写一个测试,确保这个函数在点击元素时实际运行——这就是我遇到的问题

下面是一个JSFIDLE来说明我的问题:

控制器包含一个函数
clickFunction()
,应在单击时调用该函数。单元测试应该模拟对指令元素的点击,从而触发对该函数的调用

clickFunction
是用sinonjs模拟的,这样我就可以检查它是否被调用了。该测试失败,意味着没有点击

我做错了什么

我已经看到了类似问题的答案,例如,但我不想使用完整的jQuery,我相信我在嘲笑(监视)正确的函数


下面是上面小提琴中的js(对于那些喜欢在这里看到它的人):

angular.js
angular mocks.js
也被加载

// App
var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function($scope) {
    $scope.person = 'Mr';
    $scope.clickFunction = function() {
        // Some important functionality
    };
});

myApp.directive('pers', function() {
    return {
        restrict: 'E',
        template: '<h2 ng-click="clickFunction()" ng-model="person">Person</h2>',
    };
});

// Test suite
describe('Pers directive', function() {
    var $scope, $controller, template = '<pers></pers>', compiled;
    beforeEach(module('myApp'));

    beforeEach(inject(function($rootScope, $controller, $compile) {
        $scope = $rootScope.$new();
        ctrl = $controller('MyCtrl', {$scope: $scope});
        compiled = $compile(template)($scope);

        // Do I need to run a $scope.$apply() here?
        console.log($scope.$apply); // This is a function, apparently.
        //$scope.$apply();            // But running it breaks this function.
    })); 

    it('should render directive', function() {
        el = compiled.find('h2');
        expect(el.length).to.equal(1);
    });

    it('should run clickFunction() when clicked', function() {
        el = compiled.find('h2');
        sinon.spy($scope, 'clickFunction');

        // Here's the problem! How can I trigger a click?
        //el.trigger('click');
        //el.triggerHandler('click');
        expect($scope.clickFunction.calledOnce).to.be.true
    });
});

// Run tests
mocha.run();
//应用程序
var myApp=angular.module('myApp',[]);
myApp.controller('MyCtrl',函数($scope){
$scope.person='Mr';
$scope.clickFunction=function(){
//一些重要的功能
};
});
myApp.directive('pers',function(){
返回{
限制:'E',
模板:'人',
};
});
//测试套件
描述('Pers指令',函数(){
变量$scope,$controller,模板=“”,已编译;
在每个模块之前(模块(‘myApp’);
beforeach(注入函数($rootScope、$controller、$compile){
$scope=$rootScope.$new();
ctrl=$controller('MyCtrl',{$scope:$scope});
compiled=$compile(模板)($scope);
//我是否需要在此处运行$scope.$apply()?
log($scope.apply);//显然这是一个函数。
//$scope.$apply();//但运行它会破坏此函数。
})); 
它('应该呈现指令',函数(){
el=编译后的。查找('h2');
期望(el.长度)等于(1);
});
它('单击时应运行clickFunction()',函数(){
el=编译后的。查找('h2');
sinon.spy($scope,'clickFunction');
//问题来了!我怎样才能触发点击?
//el.触发器(“点击”);
//el.triggerHandler(“点击”);
expect($scope.clickFunction.calledOnce).to.be.true
});
});
//运行测试
mocha.run();

结果表明问题相当隐蔽

首先,
$scope.$digest
$scope.$apply
函数打破了每个函数之前的
,最终导致了整个解决方案

解决方案 不要混用有角度的版本

    • angular.js
      1.3.0版
    • angularmocks.js
      1.1.5版
    • angular.js
      1.3.0版
    • angularmocks.js
      1.3.0版
这就是问题的全部,给了我相当模糊的错误

感谢来自freenode上的#AngularJS IRC频道的FoxandXS


使用jQlite在指令上触发事件的方法很简单:

someElement.triggerHandler('click')