问题描述
我有我的指令内D3可视化。与该问题是,有大量的样板code,可以在许多其他的可视化被重用,像元素[0]设置为D3可视化的容器。所以我决定创建一个服务做的一切正在该指令所做的工作,并尽量保持自己干。
我坚持目前的测试和这是我希望得到一些帮助。我的code是如下:
I have d3 visualization inside of my directive. The problem with that is that there is a lot of boilerplate code that can be reused across many other visualizations, like setting the element[0] to the container of the d3 visualization. So I decided to create a service to do all the work that was being done in the directive and try to keep myself DRY.I'm stuck with testing at the moment and this is where I was hoping to get some help. My code is as follows
指令
angular.module('app')
.directive('barchart', function (Barchartservice) {
return {
restrict: 'E',
link: function postLink(scope, element, attrs) {
scope.$on('drawCharts',function(ev,attrs){
draw();
});
function draw(){
if(!scope.dataset) return;
var svg = Barchartservice.setContainer(svg, element);
.
.
.
.
}
}
};
});
服务
angular.module('app')
.service('Barchartservice', function Barchartservice() {
var margin = {top: 50, right: 20, bottom: 50, left: 40},
container,
width = (1120 || container.width() - 20) - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
return{
setContainer: function(svg, element){
container = angular.element(element);
svg = d3.select(element[0]).append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
return svg;
}
}
});
测试
'use strict';
describe('Service: Barchartservice', function () {
// load the service's module
beforeEach(module('clientApp'));
// instantiate service
var Barchartservice;
beforeEach(inject(function (_Barchartservice_) {
Barchartservice = _Barchartservice_;
}));
it('should insert an svg element into the barchart directive', function () {
var svg = undefined;
var element = [];
element[0] = '<barchart></barchart>';
expect(Barchartservice.setContainer()).toEqual('<barchart><svg></svg></barchart>');
});
});
错误
PhantomJS 1.9.2 (Mac OS X) Service: Barchartservice should do something FAILED
TypeError: 'undefined' is not an object (evaluating 'element[0]')
任何帮助很多AP preciated。
谢谢!
Any help is much appreciated.Thanks!
推荐答案
您需要编译的元素。当测试AngularJS你必须控制编译和链接指令到DOM树。您还需要调用范围。$适用()一旦完成为好。
You need to compile the element. When testing AngularJS you have to control compiling and linking the directives to the dom tree. You also need to call scope.$apply() once this is completed as well.
所以,首先你需要注入$编译服务,并在beforeEach DI块中的$ rootScope服务。
So first you need to inject the $compile service and the $rootScope service in the beforeEach DI block.
将的范围= $ rootScope 的在beforeEach以及让你可以参考一个干净的范围内为你的测试。
Set scope = $rootScope in the beforeEach as well so you can reference a clean scope for you tests.
var element = $compile('<barchart></barchart>')(scope);
scope.$apply();
expect(Barchartservice.setContainer()).toEqual('<barchart><svg></svg></barchart>');
这应该让你进一步,但它可能无法完全通过测试。这似乎从你的源代码,你需要广播drawCharts事件以及实际运行setContainer功能。所以这可能是一个问题为好。
This should get you further, but it may not pass the test completely. It seems from your source, that you need to broadcast a drawCharts event as well to actually run the setContainer function. So this could be an issue as well.
这篇关于测试的角度服务里面D3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!