我想测试一个返回 Promise 的函数。
在这个特定的测试中,预计 Promise 会被包含经典
message
字段的 Error 对象(在这个测试中,预计等于 "my error message"
)和我添加的名为 code
的自定义字段拒绝,其中是一个字符串(如“EACCESS”、“ERIGHT”等,在此测试中它预计等于 "EFOO"
)
我想使用 chai-as-promised 来实现这一点。
return expect(foo()).to.eventually.be.rejectedWith("my error message");
这个断言有效,但现在我也想测试
code
字段。如果您使用 Chai-As-Promised (如您所说),那么它允许链接
rejectedWith
- 并将链断言对象设置为错误对象 - 意味着 rejectedWith()
之后的任何内容
现在将断言错误。这可以让你做一些很酷的事情,比如:
return expect(foo()).to.eventually
.be.rejectedWith("my error message")
.and.be.an.instanceOf(Error)
.and.have.property('code', 'EFOO');
一些 chai 方法也是链式的,因此您可以使用它来对错误做出一些非常深层嵌套的断言:
return expect(foo()).to.eventually
.be.rejectedWith("my error message")
.and.have.property('stack')
.that.includes('myfile.js:30')
有了 ChaiAsPromised 5.1.0 版本,Keithamus 的解决方案对我不起作用 -rejectedWith 没有给我断言的错误对象,但“rejected”却给了我:
return expect(foo())
.to.be.rejected
.and.be.an.instanceOf(Error)
.and.have.property('code', 'EFOO');
用于断言多个属性
return expect(foo())
.to.be.rejected
.then(function(error) {
expect(error).to.have.property('name', 'my error message');
expect(error).to.have.property('code', 'EFOO');
});
@Markko Paas 的解决方案对我不起作用,直到我添加“最终”,否则拒绝的值始终是 {} 空对象。
return expect(foo())
.to.eventually.be.rejected
.and.be.an.instanceOf(Error)
.and.have.property('code', 'EFOO');
您可以使用
rejected.then
对错误执行复杂的测试:
it('throws a complex error', function () {
return expect(foo()).to.eventually.be.rejected.then((error) => {
expect(error.code).to.equal('expected code');
// other tests
// alternatively,
expect (error).to.eql({
foo: 'foo',
bar: 'bar
});
});
});
就我而言,由于我在
chai-as-promised
函数中使用 async
,所以我所要做的就是在 await
之前添加一个 expect(promise).to.be.rejectedWith(errorMessage)
语句,例如:
it('should reject', async () => {
await expect(promise).to.be.rejectedWith(errorMessage);
// ^^^^^
});
Chai-As-Promised 对我不起作用,因为如果你期望某些东西被拒绝并且它没有拒绝,它就不会抛出。
然后我使用了以下内容,IMO 也很有表现力:
//...
await $radioButton.click();
const executed = await(async () => {
try {
await tools.waitUntil(() => {
return consoleMessages.length === 2;
}, 1000); // 1000 is the timeout in milliseconds. waitUntil() rejects if it does timeout.
return true;
} catch (error) {
return false;
}
})();
chai.assert.strictEqual(executed, false);
使用 then 和 catch 来避免这些问题。
it('should handle error during company details retrieval', async () => {
const companyId = mongoose.Types.ObjectId();
const params = {
startDate: Date.now() - 7 * 24 * 3600 * 1000, // 7 days ago
endDate: Date.now(),
};
const companyStub = sinon
.stub(Company, 'findById')
.rejects(new Error('Database error'));
companyDashBoardInfo(companyId, params).then((result) => {
expect(result).to.be.rejectedWith(InternalServerException);
expect(
companyStub.calledOnceWithExactly(companyId, {
_id: 1,
accountAccess: 1,
}),
).to.be.true;
});
});