Jasmine 不能监视事件处理程序?
尝试使用 Jasmine 测试在单击的元素上调用事件处理程序.有一个Pad"对象,其中包含一个被点击的 DOM 元素PadElement".事件处理程序是 Pad 对象上的一个方法:
Trying to test that an event handler gets called on a clicked element with Jasmine. Have a "Pad" object that contains a DOM element "PadElement", which gets clicked. The event handler is a method on the Pad object:
GRAPH.Pad = function(graphDiv, graph) {
this.graph = graph;
this.clickHandler = function(e) {
console.log('padElement clickHandler called');
//this.graph.createVertex(e.clientX, e.clientY);
};
this.padElement = GRAPH.padElement(graphDiv, this.clickHandler);
}
GRAPH.padElement = function(graphDiv, clickHandler) {
//Initialize pad
var NS="http://www.w3.org/2000/svg";
var pad=document.createElementNS(NS,"svg");
pad.setAttributeNS(null, 'id', 'pad');
graphDiv.appendChild(pad);
pad.addEventListener('click', clickHandler)
return pad;
}
茉莉花测试:
var testDiv = document.createElement('div');
var testGraph = new GRAPH.Graph(testDiv);
var testPad = new GRAPH.Pad(testDiv, testGraph);
it('has its clickHandler function called when its padElement is clicked',
function() {
spyOn(testPad, "clickHandler");
simulateClick(testPad.padElement);
//testPad.clickHandler();
expect(testPad.clickHandler).toHaveBeenCalled();
});
但是,测试失败.请注意,事件侦听器确实被调用(console.log 通过鼠标单击和模拟单击成功写入),并且如果我直接调用 testPad.clickHandler(),Jasmine 的间谍可以拾取它.但是在实际测试中会发生什么?事件处理程序调用是否在运行时转移到不同的对象?这样做的正确方法是什么?
However, the test FAILS. Note that the event listener does get called (console.log writes successfully with a mouse click and with simulateClick), AND if I just call the testPad.clickHandler() directly Jasmine's spy can pick it up. But what happens during the actual test? Does the event handler invocation get transferred to a different object at runtime? What's the right way to do this?
推荐答案
您实际上是在测试 GRAPH.padElement
调用提供的 clickHandler
而不是 this
由GRAPH.Pad
的.clickHandlerGRAPH.padElement
调用.我会怎么做
You are actually testing that GRAPH.padElement
calls the supplied clickHandler
and not that this.clickHandler
of GRAPH.Pad
is called by GRAPH.padElement
. How I would do that is
var testDiv = document.createElement('div');
var clickHandlerSpy = jasmine.CreateSpy();
var padelement = padElement(testDiv , clickHandlerSpy);
it('has its clickHandler function called when its padElement is clicked',
function() {
simulateClick(testPad.padElement);
expect(clickHandlerSpy).toHaveBeenCalled();
});
这听起来可能与您想要实现的目标略有不同.但是在理想的单元测试世界中,你应该独立测试每个单元,所以我会首先测试 padElement
是否做了它应该做的事情(如上所述),然后编写另一个测试来确保 GRAPH.Pad
正在将正确的处理程序传递给 padElement
.现在要做到这一点,我不会直接从 GRAPH.Pad
内部创建 padElement
,而是以某种方式从外部注入它,然后在 jasmine 规范中对其进行模拟.如果您对这部分不清楚,请告诉我,我可以为您整理一些代码.
This may sound little different to what you are trying to achieve. But in ideal unit testing world you should be testing each unit independently, so I would first test that padElement
does what it's supposed to do (as above) and then write another test to make sure GRAPH.Pad
is passing correct handler to padElement
. Now to do that I would not create padElement
directly from within GRAPH.Pad
but somehow inject it from outside and then mock it in the jasmine specs. If you are not clear on this part let me know and I can put some code together for you.
相关文章