Javascript 单元测试AngularJS指令包装Snap.svg
我试图创建一个Angular指令来包装Snap.svg功能,但在单元测试中遇到了问题。到目前为止,我有一个如下的指令:Javascript 单元测试AngularJS指令包装Snap.svg,javascript,angularjs,unit-testing,snap.svg,Javascript,Angularjs,Unit Testing,Snap.svg,我试图创建一个Angular指令来包装Snap.svg功能,但在单元测试中遇到了问题。到目前为止,我有一个如下的指令: 'use strict'; angular.module('rpApp') .directive('rpSvgMap', function () { return { template: '<svg id="" width="" height=""></svg>', restrict: 'E', repl
'use strict';
angular.module('rpApp')
.directive('rpSvgMap', function () {
return {
template: '<svg id="" width="" height=""></svg>',
restrict: 'E',
replace: true,
// Don't isolate scope because we want to attach rpMap to parent scope
link: function postLink(scope, element, attrs) {
// Set up Snap.svg wrapper
scope.rpMap = Snap('#' + attrs.id);
}
};
});
'use strict';
describe('Directive: rpSvgMap', function () {
// load the directive's module
beforeEach(module('rpApp'));
var element,
scope;
beforeEach(inject(function($rootScope,$compile) {
scope = $rootScope.$new();
element =
'<rp-svg-map id="anyOldID" width="800" height="400" src="../../assets/testmap.svg"></rp-svg-map>';
element = $compile(element)(scope);
scope.$digest();
}));
describe('on initialization', function() {
it('should create an SVG element with the provided dimensions and id', function() {
expect(element.attr('id')).toBe('anyOldID');
expect(element.attr('height')).toBe('400');
expect(element.attr('width')).toBe('800');
});
it('should provide a working Snap.svg drawing surface', function() {
var testCircle = scope.rpMap.circle(100,150,200);
expect(testCircle.attr(cx)).toBe(100);
});
});
到指令的链接函数,则此测试通过:
it('should tell us when Snap.svg is available', function() {
expect(scope.hasSnap).toBe(true);
});
it('should provide a working Snap.svg drawing surface', function() {
var testCircle = scope.rpMap.circle(100,150,200);
expect(testCircle.attr('cx')).toBe('100');
expect(testCircle.attr('cy')).toBe('150');
expect(testCircle.attr('r')).toBe('200');
});
Snap()不是异步的,将beforeAll/it更改为异步模式没有帮助
你知道我这里做错了什么吗?我找到的这个JSFIDLE(对不起,不记得源代码)包含解决方案
具体来说,我们可以直接将元素传递给Snap,如下所示:
scope.rpMap = Snap(element[0]);
以这种方式创建rpMap时,以下测试通过:
it('should tell us when Snap.svg is available', function() {
expect(scope.hasSnap).toBe(true);
});
it('should provide a working Snap.svg drawing surface', function() {
var testCircle = scope.rpMap.circle(100,150,200);
expect(testCircle.attr('cx')).toBe('100');
expect(testCircle.attr('cy')).toBe('150');
expect(testCircle.attr('r')).toBe('200');
});
我想这种方法的一个潜在问题是,我不一定需要或不想让所有Snap.svg方法都暴露在$scope中——我认为理想情况下,图形化的东西都应该包含在指令中
注意,在我最初的测试中也有一个小的输入错误,应该是
expect(testCircle.attr('cx')).toBe('100');
理想情况下,您应该模拟
Snap
,因为您不需要测试它是否工作,只需要您的指令调用它即可。我会把它变成一个间谍,并期望(Snap).tobeencalledwith(“#anyOldID”)
。看,也许我遗漏了一些关于设计指令的最佳方法。最终的目标是,该指令将加载SVG,根据内容创建/修改一些模型,将元素绑定到范围内的其他数据,等等。如果测试套件看不到Snap允许我在指令内执行的任何操作,那么将很难进行测试。不过,您不需要测试Snap
。如果您正在测试您的指令和Snap
,那么这不是单元测试。我终于明白了这一点。你想写下你的第一条评论作为回答吗?(我下面的答案希望能帮助有相同Snap.svg问题的人,但您的答案是我实际测试问题的正确答案)