如何使用Jasmine断言点击事件触发了间谍函数的调用?

13

我正在编写一个简单的点击处理程序,需要传入事件对象(如下所示)

Thing = function($){

    var MyObject = function(opts){
        this.opts = opts;
    };

    MyObject.prototype.createSomething = function(){
        var that = this;
        $('#some_dom_element').live('click', function(e) {
            that.doStuff(e);
        });
    };

    MyObject.prototype.doStuff = function(e) {
        //do some javascript stuff ...
        e.preventDefault();
    };

    return MyObject;

}(jQuery);

目前在我的jasmine规范中,我有一些东西来监听我期望被调用的函数(但由于它带有e参数而不是没有参数,所以我的断言失败了)。

    it ("live click handler added to the dom element", function(){
        var doSpy = spyOn(sut, 'doStuff');
        sut.createSomething();
        $("#some_dom_element").trigger('click');
        expect(doSpy).toHaveBeenCalledWith();
    });

我应该如何更正这个“toHaveBeenCalledWith”以使其按照我的期望工作?


更新

我无法按照原样使用被接受的答案,但我能够稍微修改它,下面是我的100%工作示例:

    it ("should prevent default on click", function(){
        var event = {
            type: 'click',
            preventDefault: function () {}
        };
        var preventDefaultSpy = spyOn(event, 'preventDefault');
        sut.createSomething();
        $("#some_dom_element").trigger(event);
        expect(preventDefaultSpy).toHaveBeenCalledWith();
    });
2个回答

17

你需要触发自己的事件,并传递一个用于stopPropagation方法的监视器,因为你想测试事件是否被停止。

var event = {
    type: 'click',
    stopPropagation: function(){}
}
var spy = spyOn(event, 'stopPropagation');
$('#some_dom_element').trigger(event);
expect(spy).toHaveBeenCalled();

注意:当你对要测试的对象进行间谍(spys)操作时,存在代码异味(smell),因为你开始测试类的内部行为。把你的函数视为一个黑匣子并仅测试输入和输出。在你的情况下,将函数命名更改为“in”将破坏测试,而代码仍然有效。


如何在Jasmine中断言自定义事件?例如,如果事件名称为“create”,那么我们该如何进行断言。 - Parthi

2
如果您无法使用jQuery,可以使用dispatchEvent并检查其返回值(基于此答案)。
const domElem = document.getElementById('some_dom_element');
const clickEvent = new MouseEvent('click', {
  view: window,
  bubbles: true,
  cancelable: true
});

const cancelled = !domElem.dispatchEvent(clickEvent);
expect(cancelled).toBeTruthy();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接