如何用 jest 测试 express 中的异步 error/exception 处理程序

How to test an async error/exception handler in express with jest

我是开发新手,正在尝试使用 TDD 构建我的第一个项目。我从一个应该捕获异步路由处理程序中的错误的教程中获得了这个函数(handleAsync)。为了真正理解它是如何工作的,我正在尝试进行一些测试。

./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

  });
});

我收到以下错误

● 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)

我可能正在做一些非常愚蠢的事情,但如果有人能帮助 and/or 指出正确的方向,那就太棒了。不要犹豫,说什么 wrong/stupid。我渴望学习。

回想一下 handleAsync 不执行处理程序 - 它只创建中间件。您还希望它 而不是 抛出,而是通过 next 回调传递错误。这就是您使用这样的中间件的原因 - 因此您可以拥有 async 路由处理程序并将任何可能的错误自动传递给 next,以便将错误传递给您的 error handler .

您可以测试它是否真的从包装的路由处理程序中捕获到承诺拒绝。这是一个我还没有机会测试的例子:

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);
  });
});

还有一个名为 express-async-handler which provides the same functionality as your handleAsync. You might be interested in taking a look how it does its tests 的软件包。