tpg*_*tin 7 javascript bdd jquery sinon d3.js
我在试图让我的测试通过时遇到了麻烦.我希望能够使用间谍来检查鼠标悬停事件是否被正确调用.目前我收到以下错误,"错误:预计至少被调用一次,但从未被调用".我的部分困惑与d3和jQuery选择器之间的差异有关,我非常乐意使用后者,但我不确定如何在测试中正确使用前者来获得我想要的结果.
我的依赖是d3,jQuery,mocha,chai,sinon和sinon-chai.
我的index.html文件中的相关代码,
<script src="fixtures.js"></script>
<div id="mocha"></div>
<script src="mocha.js"></script>
<script src="chai.js"></script>
<script src="sinon-chai.js"></script>
<script src="sinon-1.10.2.js"></script>
<script>
mocha.ui('bdd');
mocha.reporter('html');
var expect = chai.expect;
</script>
<script src="tests.js"></script>
<script>
mocha.run();
</script>
Run Code Online (Sandbox Code Playgroud)
fixtures.js,
var path = svg.selectAll("path")
.data(pie(data))
.enter().append("path").attr("class", "path")
.style("fill", function(d, i) { return color(i); })
.attr("d", arc)
.on("mouseover", function() { d3.select(this).style("fill", "#ff0000"); })
.on("mouseout" , function() { d3.selectAll("path").style("fill", function(d, i) { return color(i); }); });
// I wanted to test my understanding of d3 selectors
var path_one = d3.select('.path').attr("id", "path_one");
Run Code Online (Sandbox Code Playgroud)
tests.js,
describe('Donut Chart', function() {
describe("Mouseover events", function() {
it("should call on('mouseover')", function () {
var spy = sinon.spy(path, "on");
$('path').mouseenter();
sinon.assert.called(spy);
});
});
});
Run Code Online (Sandbox Code Playgroud)
这里有一些问题; 我们可以理清你的语法,但我们也必须弄清楚这个意图.
错误消息"错误:预计on至少被调用一次但从未被调用过"是准确的.on在测试期间不会调用.它只在你的灯具中调用,用于设置事件处理程序.你也在触发一个mouseenter事件,但你的听众是为了mouseover和mouseout.在现实世界中,你会mouseover在mouseenter事件发生后很快得到,但是当你用jQuery伪造它时就不会发生.无论如何,jQuery是一个非首发; 见下文.
您可以尝试通过将它们从匿名函数更改为名称来修复此问题,如下所示:
var mouseOverHandler = function() {
d3.select(this).style('fill', '#ff0000');
};
Run Code Online (Sandbox Code Playgroud)
然后将它绑定到你的path身上path.on('mouseover', mouseOverHandler).你认为你现在可以窥探mouseOverHandler,但这也行不通.当你打电话时on,你的功能会被绑定,所以稍后将它换成一个Sinon间谍将不会有任何影响.
另一个问题是你不能使用jQuery来触发D3事件,因为jQuery事件不是DOM事件.所以你应该把你的调用替换$('path').mouseenter()成类似的东西document.getElementById('path_one').dispatchEvent(new MouseEvent('mouseover'));(注意这是将代码从" mouseenter所有路径mouseover上的触发器"改为"触发带有id的元素path_one").
你可以通过重构来进行改进,这样你就可以用你可以窥探的东西来换掉你的回调,但从根本上说你是在测试错误的东西.基本上,你正在尝试为D3编写测试; "当我添加一个事件监听器时,请确保调用事件监听器." 相反,你应该测试你的实际代码的行为:"当某人鼠标悬停在图表上时,它的颜色应该改变".
如果你真的想断言你的事件处理程序是绑定的,你可以这样做:
expect(path.on('mouseover')).to.be.a('function')
Run Code Online (Sandbox Code Playgroud)
但是如果你想确保改变你的颜色,你希望你的测试如下:
describe("Mouseover events", function() {
it("should update the colours when a user mouses over the paths", function () {
var oldColor = path.style('fill');
document.getElementById('path_one').dispatchEvent(new MouseEvent('mouseover'));
expect(path.style('fill')).to.not.equal(oldColor);
});
});
Run Code Online (Sandbox Code Playgroud)