Node.js 我如何测试使用Sinon是否已经等待(而不仅仅是创建)了承诺?

Node.js 我如何测试使用Sinon是否已经等待(而不仅仅是创建)了承诺?,node.js,sinon,sinon-chai,Node.js,Sinon,Sinon Chai,假设我有一个函数: const someAction = async(): Promise<string> => { /* do stuff */ }; 相反,应该是这样的: await someAction(); 现在,我可以检查此操作是否已运行: const actionStub = sinon.stub(someAction); expect(actionStub).to.have.been.calledWith(); 但最简洁的方式是什么来检查这个承诺是否

假设我有一个函数:

const someAction = async(): Promise<string> => {
    /* do stuff */
};
相反,应该是这样的:

await someAction();
现在,我可以检查此操作是否已运行:

const actionStub = sinon.stub(someAction);
expect(actionStub).to.have.been.calledWith();
但最简洁的方式是什么来检查这个承诺是否得到了遵守


我自己也知道该如何实施,但我怀疑它一定已经在信农或信农柴实施过,我就是找不到任何东西。

我可以肯定地说,信农或信农柴没有类似的东西

这是测试任何未使用结果的基于承诺的函数所固有的困难。如果使用了结果,您知道在继续使用所述结果之前必须解决承诺。如果不是这样,事情就会变得更加复杂,超出了sinon使用简单存根为您所能做的范围

一种简单的方法是用一个伪操作来存根操作,该伪操作设置一些变量(测试的本地变量)来跟踪状态。像这样:

let actionComplete=false;
const actionStub=sinon.stub(someAction.callsFake)(()=>{
返回新承诺((解决)=>{
setImmediate(()=>{
actionComplete=true;
解决();
});
});
});
expect(actionStub.to.have.been.calledWith();
期望(动作完成)是真实的;
当然,这里的问题是等待任何承诺(不一定是这个特定的承诺)都将通过此测试,因为变量将在事件循环的下一步设置,而不管是什么原因导致您等待下一步

例如,您可以在测试代码中使用如下内容来通过测试:

someAction();
等待新的承诺((决心)=>{
setImmediate(()=>resolve());
});
更可靠的方法是创建两个单独的测试。一个承诺解决,一个承诺拒绝。您可以进行测试,以确保拒绝会导致包含函数以相同的错误进行拒绝,如果该特定承诺未被
wait
ed,则无法执行该错误

const actionStub=sinon.stub(someAction.resolves();
//在一次测试中
expect(actionStub.to.have.been.calledWith();
//在另一个测试中
const actionError=新错误(“omg错误”);
actionStub.拒绝(actionError);
//假设您的测试框架支持从测试返回承诺。
返回函数undertest()
.然后(()=>{
抛出新错误(“承诺应已拒绝”);
},(错误)=>{
expect(err).to.equal(actionError);
});

一些断言库和扩展(可能如承诺的那样)可能有一种方法来清理去糖承诺的使用。我不想对您正在使用的工具作太多假设,只想确保您的想法得到理解。

这是一个令人惊讶的详细答案,非常感谢!我喜欢拒绝方法,它似乎非常有效(并且易于实现)来防止这样的bug。感谢您提醒我在快乐之路之外测试输入的重要性。
const actionStub = sinon.stub(someAction);
expect(actionStub).to.have.been.calledWith();