假设我有一个功能:
const someAction = async(): Promise<string> => {
/* do stuff */
};我有一些代码只需要运行这个操作,忽略结果。但我有个错误-我不想让行动完成:
someAction();相反,它应该是这样的:
await someAction();现在,我可以检查这个操作是否运行过:
const actionStub = sinon.stub(someAction);
expect(actionStub).to.have.been.calledWith();但是,有什么最简洁的方式来检查这个承诺是否被等待过呢?
我自己也知道如何实现,但我怀疑它一定已经在神州或神舟中实现了,我只是什么也找不到。
发布于 2019-10-04 14:04:40
我可以肯定地说,这样的事情在罪人或罪孽中是不存在的。
在没有使用结果的情况下,这是测试任何基于承诺的函数所固有的困难。如果使用结果,您知道在继续进行所述结果之前,必须解决承诺。如果不是的话,事情就会变得更加复杂,超出了一个简单存根对你的影响范围。
一种天真的方法是用一个假的设置变量(您的测试的本地变量)来跟踪状态的操作存根。就像这样:
let actionComplete = false;
const actionStub = sinon.stub(someAction).callsFake(() => {
return new Promise((resolve) => {
setImmediate(() => {
actionComplete = true;
resolve();
});
});
});
expect(actionStub).to.have.been.calledWith();
expect(actionComplete).to.be.true;当然,这里的问题是,等待任何承诺,而不一定是这个特定的承诺,都会通过这个测试,因为变量将被设置在事件循环的下一步,而不管是什么导致您等待下一步。
例如,您可以在所测试的代码中使用这样的代码传递:
someAction();
await new Promise((resolve) => {
setImmediate(() => resolve());
});一种更健壮的方法是创建两个独立的测试。一个承诺得到了解决,一个承诺被拒绝了。您可以进行测试,以确保拒绝导致包含函数使用相同的错误拒绝,如果该特定的承诺没有被await编辑,这是不可能的。
const actionStub = sinon.stub(someAction).resolves();
// In one test
expect(actionStub).to.have.been.calledWith();
// In another test
const actionError = new Error('omg bad error');
actionStub.rejects(actionError);
// Assuming your test framework supports returning promises from tests.
return functionUnderTest()
.then(() => {
throw new Error('Promise should have rejected');
}, (err) => {
expect(err).to.equal(actionError);
});一些断言库和扩展(可能是chai承诺的)可能有一种方法来清理去糖承诺的使用。我不想过多地假设你正在使用的工具,只是试图确保这个想法被传播。
https://stackoverflow.com/questions/58219901
复制相似问题