使用 Sinon 测试 D3 中的鼠标悬停事件

2024-04-13

我在试图通过测试时遇到了麻烦。我希望能够使用间谍来检查鼠标悬停事件是否被正确调用。目前,我收到以下错误:“错误:预计已被调用至少一次但从未被调用”。我的部分困惑与 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>

固定装置.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"); 

测试.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);
        });
    });
});

这里有几个问题;我们可以理清你的语法,但我们也必须理清意图。

错误消息“错误:预期on“至少被叫过一次但从未被叫过”是准确的。on测试期间不会被调用。它仅在您的装置中调用,以设置事件处理程序。您还触发了mouseenter事件,但你的听众是为了mouseover and mouseout。在现实世界中,你会得到一个mouseover不久之后mouseenter事件,但是当你用 jQuery 伪造它时,这不会发生。无论如何,jQuery 都不是一个入门者。见下文。


您可以尝试通过将它们从匿名函数更改为命名函数来解决此问题,如下所示:

var mouseOverHandler = function() { 
    d3.select(this).style('fill', '#ff0000');
};

然后将其绑定到您的path with path.on('mouseover', mouseOverHandler)。你认为你现在可以监视mouseOverHandler, but 那也行不通。当你调用时你的函数将会被绑定on,所以以后换成诗浓间谍不会有任何效果。

jQuery 触发不适用于 D3

另一个问题是你不能使用 jQuery 触发 D3 事件,因为 jQuery 事件不是 DOM 事件 https://github.com/mbostock/d3/issues/906。所以你应该将你的电话替换为$('path').mouseenter()类似的东西document.getElementById('path_one').dispatchEvent(new MouseEvent('mouseover'));(请注意,这正在更改“触发mouseenter在所有路径上“到”触发mouseover在具有 id 的元素上path_one").

测试错误的东西

你可以通过重构来解决这个问题can用你可以监视的东西替换你的回调,但从根本上来说你正在测试错误的东西。本质上,您正在尝试为 D3 编写测试; “当我添加事件侦听器时,请确保调用该事件侦听器。”相反,您应该测试实际代码的行为:“当有人将鼠标悬停在图表上时,其颜色应该改变”。

If you really想要断言您的事件处理程序已绑定,您可以这样做:

expect(path.on('mouseover')).to.be.a('function')

但如果你想确保你的颜色改变了,你希望你的测试如下:

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);
    });
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Sinon 测试 D3 中的鼠标悬停事件 的相关文章

随机推荐