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

5
我有一个普通的Angular应用程序,其中包含一个指令。该指令包含一个带有ng-click="clickFunction()"调用的元素。当我点击该元素时一切正常。现在我需要为此点击编写一个测试,确保在单击该元素时实际运行了此函数-这就是我遇到问题的地方。
这里有一个jsfiddle来说明我的问题:http://jsfiddle.net/miphe/v0ged3vb/ 控制器包含一个名为clickFunction()的函数,应在单击时调用。单元测试应模拟对指令元素的单击,从而触发对该函数的调用。 clickFunction使用sinonjs进行了模拟,以便我可以检查它是否被调用。该测试失败,这意味着没有单击。
我在这里做错了什么?
我已经看到了类似问题的答案,例如Testing JavaScript Click Event with Sinon,但我不想使用完整的jQuery,并且我相信我正在模拟(监视)正确的函数。
以下是上述jsfiddle中的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();
1个回答

7
原来问题相当难以发现。
首先,$scope.$digest$scope.$apply函数破坏了beforeEach函数,这最终导致了整个解决方案的失败。
解决方法: 不要混合使用不同版本的Angular。 这就是整个问题所在,并给我带来了相当晦涩的错误提示。
感谢#AngularJS IRC频道上的Freenode的Foxandxss。
使用jQlite触发指令上的事件非常简单: someElement.triggerHandler('click');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接