如何使用 mocha、promises 和 catch 块防止误报
How to prevent false positives with mocha, promises, and catch blocks
我想利用 Mocha 内置的 promise 支持,但是当我想测试我的 promise 链中的 catch
个分支时,我很难处理误报。
This 问题最接近我想要的,但解决方案要求我项目中的每个开发人员添加一个 then
将引发错误,并确保该错误不会意外通过测试。
因此,我不得不恢复使用 done
风格的测试,它依赖于内置超时来捕获错误而不是断言。这不太理想,但消除了误报的可能性。
var RSVP = require('RSVP');
function request (shouldSucceed) {
if (shouldSucceed) {
return RSVP.Promise.resolve('success');
} else {
return RSVP.Promise.reject(new Error('failure'));
}
}
describe('request', function () {
it('throws an error if shouldSucceed is not provided', function () {
// this test is incorrectly calling `request`
// which leads to it passing without actually testing
// the behaviour it wants to
return request(true)
.catch(function (err) {
expect(err).to.be.an.instanceof(Error)
});
});
it('throws an error if shouldSucced is not provided (manual then block)', function () {
// this test tacks a `then` onto the chain, to ensure `request`
// actually throws an error as expected
// unfortunately, it still passes since the assertion needs to do
// a little extra work to ensure the type of error thrown is the
// expected error
return request(true)
.then(function () {
throw new Error('Not expected');
})
.catch(function (err) {
expect(err).to.be.an.instanceof(Error)
});
});
it('throws an error if shouldSucceed is not provided (done syntax)', function (done) {
// this assertion fails (as it should)
// due to a timeout
return request(true)
.catch(function () {
expect(err).to.be.an.instanceof(Error);
done()
});
});
});
输出:
request
✓ throws an error if shouldSucceed is not provided
✓ throws an error if shouldSucced is not provided (manual then block)
1) throws an error if shouldSucceed is not provided (done syntax)
2 passing (2s)
1 failing
1) request throws an error if shouldSucceed is not provided (done syntax):
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
有没有更简洁的方式告诉 mocha 我期望在 catch
块中发生某些事情,并且成功解决承诺应该是测试失败?
您正在寻找
it('request(false) should throw an error', function () {
return request(false).then(function() {
throw new Error('unexpected success');
}, function(err) {
expect(err).to.be.an.instanceof(Error)
});
});
请参阅 When is .then(success, fail) considered an antipattern for promises? 以了解与您当前拥有的代码的区别。
我想利用 Mocha 内置的 promise 支持,但是当我想测试我的 promise 链中的 catch
个分支时,我很难处理误报。
This 问题最接近我想要的,但解决方案要求我项目中的每个开发人员添加一个 then
将引发错误,并确保该错误不会意外通过测试。
因此,我不得不恢复使用 done
风格的测试,它依赖于内置超时来捕获错误而不是断言。这不太理想,但消除了误报的可能性。
var RSVP = require('RSVP');
function request (shouldSucceed) {
if (shouldSucceed) {
return RSVP.Promise.resolve('success');
} else {
return RSVP.Promise.reject(new Error('failure'));
}
}
describe('request', function () {
it('throws an error if shouldSucceed is not provided', function () {
// this test is incorrectly calling `request`
// which leads to it passing without actually testing
// the behaviour it wants to
return request(true)
.catch(function (err) {
expect(err).to.be.an.instanceof(Error)
});
});
it('throws an error if shouldSucced is not provided (manual then block)', function () {
// this test tacks a `then` onto the chain, to ensure `request`
// actually throws an error as expected
// unfortunately, it still passes since the assertion needs to do
// a little extra work to ensure the type of error thrown is the
// expected error
return request(true)
.then(function () {
throw new Error('Not expected');
})
.catch(function (err) {
expect(err).to.be.an.instanceof(Error)
});
});
it('throws an error if shouldSucceed is not provided (done syntax)', function (done) {
// this assertion fails (as it should)
// due to a timeout
return request(true)
.catch(function () {
expect(err).to.be.an.instanceof(Error);
done()
});
});
});
输出:
request
✓ throws an error if shouldSucceed is not provided
✓ throws an error if shouldSucced is not provided (manual then block)
1) throws an error if shouldSucceed is not provided (done syntax)
2 passing (2s)
1 failing
1) request throws an error if shouldSucceed is not provided (done syntax):
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
有没有更简洁的方式告诉 mocha 我期望在 catch
块中发生某些事情,并且成功解决承诺应该是测试失败?
您正在寻找
it('request(false) should throw an error', function () {
return request(false).then(function() {
throw new Error('unexpected success');
}, function(err) {
expect(err).to.be.an.instanceof(Error)
});
});
请参阅 When is .then(success, fail) considered an antipattern for promises? 以了解与您当前拥有的代码的区别。