我试图使用Jasmine触发d3事件。特别是,我想检查我的事件监听器是否使用Jasmine间谍进行调用。
例如,如果我将d3缩放行为附加到svg元素(我的前端使用Backbone.js):
代码(a):
class MyView extends Backbone.View
initialize: ->
zoom = d3.behavior.zoom().on("zoom", this.zoom_listener)
d3.select(this.el).append("svg").attr("class", "viewport").call(zoom)
zoom_listener: ->
console.log("zoom called")
Jasmine的以下测试失败:
代码(b):
it "calls zoom listener on dblclick", ->
zoom_spy = spyOn(MyView.prototype, "zoom_listener").andCallThrough()
view = new MyView()
view.$(".viewport").trigger("dblclick")
waitsFor((-> zoom_spy.callCount == 1), "Call zoom", 1000)
另一方面,(就像健全性检查一样)如果我将“dblclick”事件绑定到我的视图,如下所示,则上述测试即代码(b)将通过:
代码(c):
class MyView extends Backbone.View
events:
"dblclick" : "zoom_listener"
initialize: ->
zoom = d3.behavior.zoom().on("zoom", this.zoom_listener)
d3.select(this.el).append("svg").attr("class", "viewport")
# .call(zoom) # commented off this line for the sanity check
zoom_listener: ->
console.log("zoom called")
任何人都可以给我一些见解,为什么我似乎无法在Jasmine测试中触发D3变焦事件,即代码(b)使用我上面的原始视图,即Code(a)?
答案 0 :(得分:5)
Backbone触发jQuery事件,它似乎没有在jQuery世界之外注册。解释了一些解决方法here。但这是使用Jasmine测试D3事件的一般方法。
it('should trigger a callback on custom events', function() {
fixture.datum(dataset)
.call(barChart);
var callback = jasmine.createSpy("filterCallback");
barChart.on('customHover', callback);
var bars = fixture.selectAll('.bar');
bars[0][0].__onmouseover();
var callBackArguments = callback.argsForCall[0][0];
expect(callback).toHaveBeenCalled();
expect(callBackArguments).toBe(dataset[0]);
});
D3公开DOM对象上的事件。所以你可以附上一个间谍并触发它。
答案 1 :(得分:0)
正如M. {Bostock在https://github.com/mbostock/d3/issues/906中所述:“jQuery触发器不会调度真实事件;它只调用自己的侦听器。”
使用vanilla JS调度真实事件的一种方法是(根据How to invoke "click" event programmatically in d3?中用户“handler”的回复):
代码(b-modified)
it "calls zoom listener on dblclick", ->
zoom_spy = spyOn(MyView.prototype, "zoom_listener").andCallThrough()
view = new MyView()
jQuery.fn.custom_mouse_dblclick = (->
this.each(((i, element) ->
evt = document.createEvent("MouseEvent")
evt.initMouseEvent(
"dblclick",
true,
true,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null)
element.dispatchEvent(evt)
))
)
view.$(".viewport").custom_mouse_dblclick()
waitsFor((-> zoom_spy.callCount == 1), "Call zoom", 1000)
因此,在原始问题的代码(a)中执行代码(b修改)中的Jasmine测试,即带有d3.zoom()行为的svg元素。
答案 2 :(得分:0)
@Biovisualize的示例变体:
fixture.datum(dataset).call(barChart);
var callback = jasmine.createSpy("filterCallback");
barChart.on('customHover', callback);
//to trigger all elements
fixture.selectAll('.bar').each(function() {
this.__onmouseover();
});
expect(callback).toHaveBeenCalled();