我正在使用jasmine
对d3.js
图表中的某些互动进行单元测试。我一直在使用d3.timerFlush()
来完成动画的执行。这适用于输入新元素或更新属性时,我能够准确地测试新值。但是,我很难将其删除元素。
我有这样的方法:
exit() {
let arcs = svg.selectAll("path.arc");
arcs.transition().duration(1000)
.attrTween("d", function(d, i) { return vm._arcTween(this, d) })
.remove();
}
我的测试看起来像这样:
it('it will remove all of the pie related elements from the DOM', () => {
chartSvc.exit();
d3.timerFlush();
let elements = svg.querySelectorAll(/* selects my elements */);
expect(elements.length).toEqual(0);
});
失败了。如果我调试测试,我可以看到元素没有被删除。但是如果我改变了期望:
expect(pieChartSvc._arcTween).toHaveBeenCalled();
传递,所以我知道该方法正在正确执行并且计时器已刷新,但元素未被删除。
我做错了什么?
此问题:Disabling all D3 animations (for testing) 不回答我的问题。正在执行转换,并且元素已经更改为它们从DOM中删除之前所处的状态,但是它们仍然出现在DOM上
答案 0 :(得分:4)
好吧,想通了,d3
版本3曾用date.now
来衡量时间。版本4移至performance.now。
所以,正确的代码应该是:
it('it will remove all of the pie related elements from the DOM', () => {
chartSvc.exit();
performance.now = function() { return Infinity; };
d3.timerFlush();
let elements = svg.querySelectorAll(/* selects my elements */);
expect(elements.length).toEqual(0);
});
这是一些测试代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
<style>
path {
fill: none;
stroke: steelblue;
}
</style>
</head>
<body>
<svg width="300" height="300">
<g transform="translate(20,20)">
<path class="arc" d="M0,0L100,0"></path>
<path class="arc" d="M0,50L100,50"></path>
<path class="arc" d="M0,100L100,100"></path>
<path class="arc" d="M0,150L100,150"></path>
</g>
</svg>
<script>
var svg = d3.select('svg');
let arcs = svg.selectAll("path.arc");
arcs.transition()
.duration(10000)
.remove();
performance.now = function() { return Infinity; };
d3.timerFlush();
</script>
</body>
</html>