Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果一个接一个地(同步地)调用事件处理程序,则进行单元测试_Javascript_Unit Testing_Vue.js_Jestjs_Vue Test Utils - Fatal编程技术网

Javascript 如果一个接一个地(同步地)调用事件处理程序,则进行单元测试

Javascript 如果一个接一个地(同步地)调用事件处理程序,则进行单元测试,javascript,unit-testing,vue.js,jestjs,vue-test-utils,Javascript,Unit Testing,Vue.js,Jestjs,Vue Test Utils,我有一个Vue按钮单击处理程序,它基于所需的参数,可以: 打电话只是请求 打电话只是请求B 调用请求A和B-但是如果请求A成功返回,它应该依次调用它们,然后调用请求B。基本上,实现不能使用Promise.all。 我的问题是,我不知道如何用Jest一个接一个地对调用A和B进行单元测试 实施 这是事件处理程序,它在单击按钮后运行: const loadA=此.store.dispatch['loadA']//注意,这些函数返回一个承诺 const loadB=this.$store.dispatc

我有一个Vue按钮单击处理程序,它基于所需的参数,可以:

打电话只是请求 打电话只是请求B 调用请求A和B-但是如果请求A成功返回,它应该依次调用它们,然后调用请求B。基本上,实现不能使用Promise.all。 我的问题是,我不知道如何用Jest一个接一个地对调用A和B进行单元测试

实施 这是事件处理程序,它在单击按钮后运行:

const loadA=此.store.dispatch['loadA']//注意,这些函数返回一个承诺 const loadB=this.$store.dispatch['loadB']; 异步makeRequestsshouldMakeRequestA、shouldMakeRequestB{ 常量请求=[]; ifshouldMakeRequestA requests.pushloadA; ifshouldMakeRequestB requests.pushloadB; 请求中的forconst请求{ 等待请求;//在调用第二个请求之前,等待请求返回 } } 测试 正确的测试用例应该:

失败❌ 当:

该实现同时调用两个请求,例如:

=>{Promise.all[loadA,loadB]} =>{loadA;loadB} 通过✔️ 当:

该实现调用loadA,等待其承诺得到解决,然后调用loadB,例如: =>{等待加载A;等待加载B;} 下面是我对我描述的测试用例的看法,但它对于比赛条件来说似乎非常脆弱,我认为同事们很难理解

//component.spec.js 从“@/components/MyCustomButton.vue”导入MyCustomButton 从“@/components/TheComponentWeAreTesting”导入组件间测试 描述'foo',=>{ 常量resolveAfterOneSecond==>new Promiser=>setTimeoutr,1000; 让包装纸; const loadA=jest.fnsolve1秒后; const loadB=jest.fnsolve1秒后; beforeach=>{ wrapper=shallowmountthecomponentwearesting,store:newvuex.store{actions:{loadA,loadB}; } 它“一个接一个地运行A和B”,异步=>{ vm.$emit'click'; /* 我的方法的一个主要问题是 我不知道在我等待下一次之后已经过了多少时间。 这两个请求在总计2000毫秒后解析,如上所述,使用setTimeout 但在$nextTick解决之后,又过了多长时间? 700ms?1300?1999ms? */ 等待wrapper.vm.$nextTick; /* 因为我不知道$nextTick花了多少时间来解决这个问题 我需要多等几毫秒,这样测试才能通过 基本上,你必须相信我的话,500ms是使测试通过的值 */ awat new Promiser=>settimeout,500; const callCount=loadA.mock.calls.length+loadB.mock.calls.length; expectcallCount.toBe1;//预期第一个请求已发出,但此时不应发出第二个请求 } } 有没有更好的方法来测试这种行为?我知道例如jest.advanceTimersByTime,但这会提前所有计时器,而不是当前计时器。

我会更换等待新的Promiser=>setTimeoutr,500;以某个处理程序为例

异步makeRequestsshouldMakeRequestA、shouldMakeRequestB{ 常量请求=[]; ifshouldMakeRequestA requests.pushloadA; ifshouldMakeRequestB requests.pushloadB; 请求中的forconst请求{ 等待请求;//在调用第二个请求之前,等待请求返回 } } 回报承诺

this.handler=async=>{ 常量请求=[]; 如果shouldMakeRequestA requests.pushloadA; 如果shouldMakeRequestB requests.pushloadB; 请求的常量请求{ 等待请求; } } **示例代码段**

Vue.config.devtools=false; Vue.config.productionTip=false; 常数{ 浅山 }=VuetStutils; 常数{ 核心:{ 之前,, 描述 信息技术 预料 跑 开玩笑 }, }=window.jestLite; 常量resolveAfterOneSecond==>new Promiser=>setTimeoutr,1000; 让loadA=ResolveAfter1秒; 让loadB=ResolveAfter1秒; const combineAndSendRequests=异步函数*shouldMakeRequestA、shouldMakeRequestB{ 如果你应该提出请求{ 等待加载; 产量1; } 如果你应该提出请求{ 等待加载b; 产量2; } } const TestComponent=Vue.component'test-component'{ 模板:`Send`, 资料{ 返回{ 处理程序:null } }, 方法:{ 发送请求{ const shouldMakeRequestA=true; const shouldMakeRequestB=true; this.handler=async=>{ 对于等待,让我们承诺组合AndSendRequestsShouldMakeRequestA,shouldMakeRequestB{ } }; } } } var app=新的Vue{ el:“应用程序” } document.querySelectortests.addEventListenerclick,事件=>{ 常量元素=event.target; element.dataset.running=true; element.textContent=正在运行。。。 loadA=jest.fnsolve1秒后; loadB=jest.fnsolve1秒后; descripbeCombinedSendRequests,=>{ 它“一个接一个地运行A和B”,异步=>{ const shouldMakeRequestA=true; const shouldMakeRequestB=true; 常量迭代器=combineAndSendRequestsshouldMakeRequestA,shouldMakeRequestB; 等待迭代器。下一步; 让loadacallscont=loadA.mock.calls.length; 让loadbcallscont=loadB.mock.calls.length; expectloadacallscont.toBe1; expectloadbcallscont.toBe0; 等待迭代器。下一步; loadbcallscont=loadB.mock.calls.length; expectloadbcallscont.toBe1; const callscont=loadA.mock.calls.length+loadB.mock.calls.length; expectcallsCount.toBe2; }; }; 描述测试组件,=>{ 设wrapper=null; beforeach=>{ 包装器=shallowMountTestComponent; } 它“在单击后运行请求”,异步=>{ findbutton.trigger'click'; 等待wrapper.vm.$nextTick; const handler=wrapper.vm.$data.handler; expecthandler.not.toBenull; }; }; run.thenresult=>{ console.logresult; 删除element.dataset.running; if!result.somepr=>pr.status.includesfail{ element.textContent=已通过! element.dataset.pass=true; }否则{ element.textContent=失败! element.dataset.fail=true; } } } 测验{ 页边顶部:1rem; 填充:0.5雷姆; 边框:1px纯黑; 光标:指针; } 按钮[数据传递]{ 背景:绿色; 颜色:白色; } 按钮[数据运行]{ 背景:橙色; 颜色:白色; } 按钮[数据失败]{ 背景:红色; 颜色:白色; } 运行测试I将替换wait new Promiser=>settimeout,500;以某个处理程序为例

异步makeRequestsshouldMakeRequestA、shouldMakeRequestB{ 常量请求=[]; ifshouldMakeRequestA requests.pushloadA; ifshouldMakeRequestB requests.pushloadB; 请求中的forconst请求{ 等待请求;//在调用第二个请求之前,等待请求返回 } } 回报承诺

this.handler=async=>{ 常量请求=[]; 如果shouldMakeRequestA requests.pushloadA; 如果shouldMakeRequestB requests.pushloadB; 请求的常量请求{ 等待请求; } } **示例代码段**

Vue.config.devtools=false; Vue.config.productionTip=false; 常数{ 浅山 }=VuetStutils; 常数{ 核心:{ 之前,, 描述 信息技术 预料 跑 开玩笑 }, }=window.jestLite; 常量resolveAfterOneSecond==>new Promiser=>setTimeoutr,1000; 让loadA=ResolveAfter1秒; 让loadB=ResolveAfter1秒; const combineAndSendRequests=异步函数*shouldMakeRequestA、shouldMakeRequestB{ 如果你应该提出请求{ 等待加载; 产量1; } 如果你应该提出请求{ 等待加载b; 产量2; } } const TestComponent=Vue.component'test-component'{ 模板:`Send`, 资料{ 返回{ 处理程序:null } }, 方法:{ 发送请求{ const shouldMakeRequestA=true; const shouldMakeRequestB=true; this.handler=async=>{ 对于等待,让我们承诺组合AndSendRequestsShouldMakeRequestA,shouldMakeRequestB{ } }; } } } var app=新的Vue{ el:“应用程序” } document.querySelectortests.addEventListenerclick,事件=>{ 常量元素=event.target; element.dataset.running=true; element.textContent=正在运行。。。 loadA=jest.fnsolve1秒后; loadB=jest.fnsolve1秒后; descripbeCombinedSendRequests,=>{ 它“一个接一个地运行A和B”,异步=>{ const shouldMakeRequestA=true; const shouldMakeRequestB=true; 常量迭代器=combineAndSendRequestsshouldMakeRequestA,shouldMakeRequestB; 等待迭代器。下一步; 让loadacallscont=loadA.mock.calls.length; 让loadbcallscont=loadB.mock.calls.length; expectloadacallscont.toBe1; expectloadbcallscont.toBe0; 等待迭代器。下一步; loadbcallscont=loadB.mock.calls.length; expectloadbcallscont.toBe1; const callscont=loadA.mock.calls.length+loadB.mock.calls.length; expectcallsCount.toBe2; }; }; 描述测试组件,=>{ 设wrapper=null; beforeach=>{ 包装器=shallowMountTestComponent; } 它“在单击后运行请求”,异步=>{ findbutton.trigger'click'; 等待wrapper.vm.$nextTick; const handler=wrapper.vm.$data.handler; expecthandler.not.toBenull; }; }; run.thenresult=>{ console.logresult; 删除element.dataset.running; if!result.somepr=>pr.status.includesfail{ element.textContent=已通过! element.dataset.pass=true; }否则{ element.textContent=失败! element.dataset.fail=true; } } } 测验{ 页边顶部:1rem; 填充:0.5雷姆; 边框:1px纯黑; 光标:指针; } 按钮[数据传递]{ 背景:绿色; 颜色:白色; } 按钮[数据运行]{ 背景:橙色; 颜色:白色; } 按钮[数据失败]{ 背景:红色; C 颜色:白色; }
对响应运行TestsThanks。我看到您将断言更改为expectcallCount.toBe2,但我认为运行测试用例会给出假阳性。等待this.handler将导致测试用例在loadA和loadB都已解决后继续执行-此时无法判断它们是一个接一个调用还是同时调用。我在我的问题中添加了更多的描述。事实上,测试这样的事情是很困难的,因为您无法跟踪函数中执行承诺的顺序。潜在的解决方法是异步生成器函数,如果每次迭代都调用所需函数,则可以单独测试该函数。它的示例在代码段中。不过我不推荐。谢谢你的回复。我看到您将断言更改为expectcallCount.toBe2,但我认为运行测试用例会给出假阳性。等待this.handler将导致测试用例在loadA和loadB都已解决后继续执行-此时无法判断它们是一个接一个调用还是同时调用。我在我的问题中添加了更多的描述。事实上,测试这样的事情是很困难的,因为您无法跟踪函数中执行承诺的顺序。潜在的解决方法是异步生成器函数,如果每次迭代都调用所需函数,则可以单独测试该函数。它的示例在代码段中。不过我不推荐。