我有一个带有指令的常规角度应用程序。该指令包含一个ng-click="clickFunction()"
调用的元素。单击该元素时,一切正常。我现在需要为此单击编写一个测试,确保在单击该元素时实际运行此函数 - 这就是我遇到的问题。
这是一个解释我的问题的方法:http://jsfiddle.net/miphe/v0ged3vb/
控制器包含一个函数clickFunction()
,应该在点击时调用。单元测试应模仿指令元素的单击,从而触发对该函数的调用。
使用sinonjs模拟clickFunction
,以便我可以检查它是否被调用。该测试失败,意味着没有点击。
我在这里做错了什么?
我已经看到像Testing JavaScript Click Event with Sinon这样类似问题的答案,但我不想使用完整的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();
答案 0 :(得分:7)
原来问题很隐蔽。
首先,$scope.$digest
和$scope.$apply
函数打破了beforeEach
函数,最终导致整个解决方案。
不要混合角度版本。
angular.js
版本1.3.0 angular-mocks.js
版本1.1.5 angular.js
版本1.3.0 angular-mocks.js
版本1.3.0 这就是整个问题,给了我相当模糊的错误。
感谢来自freenode的#AngularJS IRC频道的Foxandxss。
使用jQlite触发指令事件的方法很简单:
someElement.triggerHandler('click');