测试使用jQuery的Angular指令
Test an Angular directive that uses jQuery
我在为一些Angular指令编写单元测试时遇到问题。特别是那些在指令中使用jQuery的指令。我在下面设计了一个简单的例子来说明我的问题。
这个愚蠢的指令将click事件绑定到元素。单击时,它将隐藏该元素。根据Angular的说法,传递到指令中的元素将被包装为jQuery元素。如果jQuery可用,它将使用jQuery,否则它将使用Angular的jQueryLite。事实上,如果我在包含jQuery的浏览器中使用该指令,该指令会起作用,并隐藏单击的元素。
angular.module('myApp').directive('clickhide', function() { return {
link: function(scope, element, attrs) {
element.bind('click', function(e) {
element.hide();
scope.$digest();
});
}
}});
以下是该指令的Karma单元测试规范:
describe('clickhide', function() {
var scope, elm;
beforeEach(module('MyApp'));
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope;
elm = angular.element('<div clickhide></div>');
$compile(elm)(scope);
scope.$digest();
}));
it('should do a click', function() {
elm[0].click();
//OOPS: undefined is not a function error
expect($(elm).find(":hidden").length).toBe(1);
});
});
当我运行这个测试时,它失败了,错误为"未定义不是函数",这意味着没有加载jQuery,Angular使用了jQueryLite,它没有定义hide((。
我找到了两种方法来解决这个问题。
不要使用jQuery。需要重写我不想做的指令。
在我的指令中显式包装元素,使它们成为jQuery元素:
$(element).hide()
。还需要修改我的指令,我宁愿不这样做。如果别无选择,我当然可以这样做。
我觉得Angular应该可以在单元测试时自动在指令中使用jQuery,就像在web浏览器中使用一样。我相信关键点是Angular文档中的这一行:
要使用jQuery,只需在触发DOMContentLoaded事件之前加载它。
我不清楚在运行单元测试时什么时候会发生DOMContentLoaded。我的Karma配置文件包括jQuery作为第一个文件,在angular之前:
module.exports = function(config) {
config.set({
basePath: '../../',
frameworks: ['jasmine', 'ng-scenario'],
files: [
'app/bower_components/jquery/dist/jquery.min.js',
'app/bower_components/angular/angular.js',
'app/bower_components/angular-route/angular-route.js',
'app/bower_components/angular-sanitize/angular-sanitize.js',
'app/bower_components/angular-mocks/angular-mocks.js',
...
],
exclude: [],
reporters: ['progress'],
port: 9876,
runnerPort: 9100,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 60000,
singleRun: false
});
};
我需要在测试中注入jQuery吗?也许这是因果报应的限制?有人知道吗?
尝试在测试的每个块之前覆盖$in。
beforeEach(function() {
$.fn.hide = function() {
this.css( "display", "none" )
};
});
我能够通过在angular之前加载jquery来解决类似的问题。此外,如果$对您来说失败了,您可以始终使用angular.element(''(来代替$
- 将JSON对象传递给angular指令
- Angular指令在alertify setContent内容中不起作用
- 在其他javascript框架模板中运行angular指令
- 如何动态禁用Angular指令
- 在 Angular 指令中,如何进行回调,其中函数名称位于父范围的变量中
- Angular指令中的最佳实践是将文本输入设置为英尺和英寸的格式
- 不适用于动态数据的Angular指令来自$http
- 这段jquery代码在angular指令中不起作用
- Angular 指令似乎没有使用元素传入的选项执行
- 带有Angular指令的HTML;附加时无法工作
- 如何使用angular指令从html中获取数组
- 如何正确控制Angular指令的$dirty和$pure状态
- 在 Angular 指令中定义一个用于 ng-click 的函数
- HTML 标记在使用 Angular 指令时被视为纯文本
- 当 Angular 指令的名称真正重要时
- 如何将侦听器添加到 Angular 指令中
- 嵌套的Angular指令触发父对象上的作用域函数
- 在ui路由器中以Webpack块的形式懒惰地加载Angular指令
- 超链接;编译angular指令内的模板后无法工作
- 用angular指令构建嵌套树