d3.js - 用于调用svg元素点击的jasmine测试

时间:2016-03-30 15:53:49

标签: angularjs d3.js svg

我的角度应用程序中有一个图表指令,它使用了d3.js库。

该指令的一部分将鼠标事件处理程序添加到某些svg元素中,如此

svg.selectAll('g rect')
    .on('click', function(d) {
        scope.clickHandler(d, scope.data);
    })
    .on('mouseover', function () {
        d3.select(this).classed('data-item-hover', true);
    })
    .on('mouseout', function () {
        d3.select(this).classed('data-item-hover', false);
    });

我想在一些单元测试中覆盖这些处理程序,但我正在努力实现如何动态地调用这些事件。

我在我的测试规范

中尝试这个
describe('scope.clickHandler', function() {
    var rect;
    beforeEach(function(){
        spyOn(scope, 'clickHandler');
        rect = svg.select('g rect')[0][0];
        rect.on('click')();
    });
    it('should call scope.render after a window resize event occurs', function () {
        expect(scope.clickHandler).toHaveBeenCalled();
    });
});

然而,这会引发错误

  

TypeError:undefined不是构造函数(评估   ' rect.on('单击')'

我遇到了这个SO How to invoke "click" event programmatically in d3?,第二个答案是让我尝试这种技术的原因。

如何在我在d3.js中注册事件的svg元素上调用鼠标事件?

由于

1 个答案:

答案 0 :(得分:3)

主要问题是svg.select('g rect')[0][0]是一个DOM元素而不是正确的D3选择,这就是导致undefined错误的原因。来自文档:

  

选择是元素数组 - 字面意思(可能不是字面意思......)。   D3将其他方法绑定到数组,以便您可以应用   运营商到选定的元素......

您实际上可以检查,因为DOM元素实现了Element接口:

(svg.select('g rect')[0][0] instanceof Element) // true

因此,为了触发某个元素上的某个事件,您可以执行以下操作:

var rect = svg.select('g rect') // first rect element found is assumed
rect.on('click').call(rect.node(), rect.datum()); // as commented in above link

你可以找到一个简单的工作小提琴here