Javascript 断言观察到一个事件

Javascript 断言观察到一个事件,javascript,unit-testing,sinon,qunit,backbone-events,Javascript,Unit Testing,Sinon,Qunit,Backbone Events,在QUnit测试用例中,我如何断言观察到了特定的主干事件 应用程序使用(Backbone.js版本1.3.3)在组件之间进行通信。简单视图通过触发事件总线上的自定义事件来响应按钮单击: //foo.js const WheelView=Backbone.View.extend({ 活动:{ “点击#btn旋转轮”:“点击按钮点击”, }, OnSpinButton单击:函数(){ log(“调试:点击#btn旋转盘”); 主干。触发器(“轮子:旋转”); }, }); 我想要一个测试用例(QU

在QUnit测试用例中,我如何断言观察到了特定的主干事件

应用程序使用(Backbone.js版本1.3.3)在组件之间进行通信。简单视图通过触发事件总线上的自定义事件来响应按钮单击:

//foo.js
const WheelView=Backbone.View.extend({
活动:{
“点击#btn旋转轮”:“点击按钮点击”,
},
OnSpinButton单击:函数(){
log(“调试:点击#btn旋转盘”);
主干。触发器(“轮子:旋转”);
},
});
我想要一个测试用例(QUnit版本1.22.0),它断言“当选择此按钮时,事件“foo”出现在事件总线上”

测试用例还需要知道事件的其他方面(例如可选参数),因此我需要在测试用例中定义一个函数,测试用例将该函数作为特定事件的回调进行安排

这是我尝试过的最新测试用例,通过为事件回调生成Sinon(1.9.0版)间谍函数:

//test-foo.js
质量模块(“按钮”btn旋转轮“{
beforeach:函数(断言){
this.wheelView=新的wheelView();
},
之后:函数(断言){
删除此项。wheelView;
},
});
质量检验(
应观察“车轮:旋转”事件,
函数(断言){
断言。期望(1);
const spinWheelButton=document.querySelector(
“#qunit夹具#btn转轮”);
const eventListener=sinon.spy(函数(){
log(“DEBUG:quonit:received'wheel:spin'事件”);
});
主干。一次(“轮子:旋转”,eventListener);
const done=assert.async();
setTimeout(函数(){
Spinwheel按钮。单击();
setTimeout(函数(){
assert.ok(eventListener.calledOnce);
}.约束(这个);
完成();
}.绑定(本),500);
});
调用
console.log
可以帮助我了解哪些函数正在被调用,哪些函数没有被调用。我希望看到两种情况:

DEBUG:单击#btn spin wheel
调试:QUnit:收到“控制盘:旋转”事件
相反,只会显示“单击”消息:

DEBUG:单击#btn spin wheel
这是因为测试用例失败而确认的:

按钮“btn旋转轮”:应观察“旋转轮:旋转”事件。(3,0,3)579毫秒
1.最后一个'assert.async'之后的断言在578毫秒时被解析
来源:Assert.prototype。ok@file:///usr/share/javascript/qunit/qunit.js:1481:3
2.失败,预期参数是真实的,was:false@578 ms
预期:正确
结果:错误
来源:@file://[…]/test foo.html:50:29
3.应为1个断言,但在579毫秒时运行了2个断言
来源:@file://[…]/test foo.html:36:13
来源:@file://[…]/test foo.html:36:13
我已经阅读并正在试验不同的
assert.async
setTimeout
用法,如文档示例中所示。到目前为止,这是徒劳的


我应该如何使用QUnit、Sinon和主干来断言(应用程序中观察到的特定事件的存在和特定属性)?

您应该能够为您的事件注册一个侦听器,并使用
assert.async
来侦听它,如下所示:

var done = assert.async();
Backbone.once("wheel:spin", function(event) {
    done();
});

const spinWheelButton = document.querySelector("#qunit-fixture #btn-spin-wheel");
spinWheelButton.click();
可能只是因为
setTimeout
调用,您的代码没有按预期运行


您可以找到QUnit的
async

的进一步文档。问题证明是测试用例之间的交互。测试用例操纵监听器并将事件激发到事件中心;但是所有测试用例共享同一个事件中心

因此,当测试用例异步运行时,一个测试用例中触发的事件可能会影响另一个测试用例,而不是隔离测试用例

我实现的解决方法是为每个测试用例定制一个事件队列,该队列在
quonit.module中进行管理

/**
*在“testCase”期间设置事件中心装置。
*
*@param testCase:quanit测试用例,在该测试用例期间
*应该是积极的。
*@param eventHub:fixture所在的主干.Events对象
*应该存在。
*/
setUpEventsFixture:函数(testCase、eventHub){
testCase.eventHubPrevious=eventHub.\u事件;
eventHub._events=[];
},
/**
*拆除“testCase”的事件中心装置。
*
*@param testCase:quanit测试用例,在该测试用例期间
*应该是积极的。
*@param eventHub:fixture所在的主干.Events对象
*应该存在。
*/
tearDownEventsFixture:函数(testCase、eventHub){
eventHub.\u events=testCase.eventHubPrevious;
},
通过在测试模块定义中使用这些:

QUnit.module(“按钮”btn spin wheel“{
beforeach:函数(断言){
setUpEventsFixture(此为主干);
this.wheelView=新的wheelView();
},
之后:函数(断言){
删除此项。wheelView;
拆卸事件固定(此为主干);
},
});

测试用例现在可以继续使用使用公共
主干
对象作为事件中心的代码,但是它们的事件彼此隔离。

我需要测试用例断言“调用了这个特定的函数(注册的回调)”,这样我就可以知道它是如何被调用的。我不明白您的示例是如何做到这一点的。为什么您需要断言测试中定义的回调已被执行?我不知道你到底想测试什么你试过那个代码了吗?提前调用
done
会导致测试用例在运行任何其他代码之前结束,这意味着在此之后我不会做出任何断言。嗯,好吧,您的内部
setTimeout
实际上没有超时。。。这里需要第二个参数(比如
50