【发布时间】:2015-09-14 12:42:11
【问题描述】:
我有一个向元素添加点击处理程序的指令:
module.directive('toggleSection', ['$timeout', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.bind('click', function (event) {
scope.$apply(function () {
var scopeProp = 'show' + attrs.toggleSection;
event.preventDefault();
event.stopPropagation();
scope[scopeProp] = !scope[scopeProp];
return false;
});
});
}
};
}]);
当点击元素时,它会切换作用域上的另一个属性,另一个元素使用ng-show 绑定到该属性。它在应用程序中正常工作。
我为指令添加了以下测试:
(function () {
'use strict';
// get the app module from Angular
beforeEach(module('app'));
describe('myCtrl', function () {
var $scope, $rootScope;
beforeEach(inject(function ($controller, _$rootScope_) {
$scope = {};
$controller('myCtrl', { $scope: $scope });
$rootScope = _$rootScope_;
}));
describe('the toggleSection directive', function () {
var testElement;
beforeEach(function () {
testElement = $compile('<a toggle-section="Test" href="#">Collapse section</a>')($rootScope);
$rootScope.$digest();
});
it('inverts the value of the specified scope property', function () {
$scope.showTest = false;
testElement.click();
expect($scope.showTest).toEqual(true);
});
});
});
在实际代码中,有像$scope.showSection1 = false 这样的属性,通过在指令中添加控制台日志,我可以在单击绑定元素之前和之后看到属性,并且它们具有预期值(例如,属性以false 开头并且在切换元素变为true 后单击切换元素后)。
但是,测试总是以“预期假等于真”失败。我认为这与$apply 方法有关,因为当我运行测试时,范围内似乎不存在任何显示属性。
我拥有的其他测试(即使在同一个规范文件中),不使用该指令可以很好地查看范围上的属性。
我做错了什么?
【问题讨论】:
-
您应该在测试范围而不是 rootScope 中编译您的指令。试试看,如果它解决了您的问题,请告诉我。另外,不确定这是否有帮助,但我首先创建 angular.element:
element = angular.element('<my-directive/>');compile(element)(scope);scope.$digest(); -
嗨戴安娜,我试过这个(这是我唯一改变的,我离开
$digest()被$rootScope调用),但现在测试有一个错误:'undefined' is not a函数(评估 'scope.$apply') - 它在指令本身中使用 '$apply()' 时出错了..? -
如果你根据 rootScope 编译它,它将在 rootScope.$apply 中。这就是为什么我说你必须针对范围编译它,而不是 rootScope。
-
啊,好吧,这是因为您的范围没有正确创建。它应该在每个之前创建,不仅仅是
$scope = {},而是$scope = $rootScope.$new(); -
好的,谢谢你的解释!
标签: javascript angularjs unit-testing jasmine