qunit: Add assert method for rejection of promises
This would support the following:
QUnit.test('does stuff', function(assert) {
assert.throws(() => {
return new Promise((resolve, reject) => {
setTimeout(reject, 10, new Error('NOOOOOOOO!!!!!');
});
}, /NOOOOOO/);
});
An alternative would be to add a assert.rejects, but I feel like transparently supporting this case in assert.throws is more aligned with how we handle things in other areas.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 2
- Comments: 17 (17 by maintainers)
TL;DR: LGTM!
I agree the current workaround is worth trying to avoid by providing a built-in convenience method. (The workaround being the idea of returning the promise to
QUnit.testafter swapping the meaning of resolved and rejected.)At first, I wasn’t sure whether
assertis the best object for the method to exist on. We do have otherassertmethods that don’t (immediately) assert something (such asasync, andexpect). But if the method merely provides the inverted promise with an asynchronous assertion chained, that would create a potential usability hazard as the user would need to make sure to still either return the result fromassert.rejecttoQUnit.testor manually attachassert.asyncto it.However, I see now that the implementation goes beyond inverting the promise and attaching an assertion to the chain, it also adds async tracking. That was the missing puzzle piece. It does make for a more complex method, but I think in this case that overhead is worth it and makes for a very intuitive method.
One thing to keep in mind here is that this further increases the number of async-tracking methods we have in the public API.
Projects aiming to reduce or avoid multiple async things during tests, will need to keep in mind that
assert.rejectsis now one more additional pattern to look out for as being indicative of an asynchronous test (e.g. as part of code review). I don’t expect that to be a problem, but something to keep in mind (adding complexity is never cost-free).Could we create new APIs for promises around asserting that a promise resolves or rejects (possibly supporting a predicate that could be given the resolve/reject arguments and could further validate the result)? That way we can just keep the APIs for promise rejection and exception catching separate.