Reputation: 13
I'm new to development and I'm trying to build my first project with TDD. I got this function (handleAsync) from a tutorial supposed to catch errors in async route handlers. To truly understand how it works, I am trying to come up with some tests.
./utils/handle-async.js
// ./utils/handle-async.js
module.exports = (fn) => (req, res, next) => {
fn(req, res, next).catch((err) => next(err));
};
./tests/utils/handle-async.test.js
// ./tests/utils/handle-async.test.js
const handleAsync = require('../../utils/handle-async');
describe('catch errors in async functions', () => {
it('should throw an error if a promise is rejected or an error occurs', (done) => {
// const fn=async()=>await Promise.resolve(1)
const fn = async () => Promise.reject(new Error('Rejected!'));
expect(handleAsync(fn)).toThrowError('Rejected!');
done();
});
it('should not throw and error if a promise is resolved', (done) => {
// yet to be written, don't know what to do here since first test shows I don't get it yet
});
});
I get the following error
● catch errors in async functions › should throw an error if a promise is rejected or an error occurs
expect(received).toThrowError(expected)
Expected substring: "Rejected!"
Received function did not throw
7 | // console.log(typeof fn); 8 | // console.log('rejected prom:', fn); *9 | expect(handleAsync(fn)).toThrowError('Rejected!'); | ^ 10 | done(); 11 | }); 12 | at Object.<anonymous> (tests/utils/handle-async.test.js:9:29)
I'm probably doing some super dumb things but if anyone could help and/or point me in the right directions, that would be awesome. Don't hesitate to say whatever is wrong/stupid. I'm eager to learn.
Upvotes: 1
Views: 1377
Reputation: 13652
Recall that handleAsync
doesn't execute the handler - it only creates the middleware. You're also expecting it to not throw, but rather to pass the error on via the next
callback. That's the reason you're using a middleware like this - so you can have async
route handlers and have any possible errors be passed automatically to next
so that the errors get passed to your error handler.
You can test whether it actually catches a promise rejection from a wrapped route handler. Here's an example, which I haven't had the chance to test:
describe("catch errors in async functions", () => {
it("should catch rejected promises and pass the error to next", (done) => {
const rejectError = new Error("Rejected!");
const fn = async () => Promise.reject(rejectError);
const middleware = handleAsync(fn);
const req = {};
const res = {};
const next = (err) => {
expect(err).toBe(rejectError);
done();
};
middleware(req, res, next);
});
});
There's also a package called express-async-handler
which provides the same functionality as your handleAsync
. You might be interested in taking a look how it does its tests.
Upvotes: 1