Al probar el controlador de errores predeterminado de una aplicación Express, se produce un tiempo de espera. La función se ve de la siguiente manera:
const createApp = (underlyingFunction) => { const app = express() app.get('/my-endpoint', async (req, res) => { await underlyingFunction() res.send({ success: true }) }) const errorHandler: ErrorRequestHandler = (error, req, res, next) => { console.error('Unhandled exception'); console.error(error); console.error(error.stack); res.status(500).send({ message: 'Oh dear', }); // next() } app.use(errorHandler) return app; }Y la prueba queda de la siguiente manera:
test('error should be handled and return 500', async () => { underlyingFunction.mockImplementation(() => { throw new Error('Something went wrong') }) const app = createApp(underlyingFunction) const response = await request(app).get('/my-endpoint') expect(response.status).toBe(500) })Al ejecutar la prueba, me sale el siguiente error:
thrown: "Exceeded timeout of 5000 ms for a test. Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."¿Qué podría estar causando esto?
Para express V4 , del documento Manejo de errores # Captura de errores, sabemos:
Para los errores devueltos por funciones asincrónicas invocadas por controladores de ruta y middleware, debe pasarlos a la función
next(), donde Express los detectará y procesará.
Aunque la underlyingFunction del simulacro en el caso de prueba es síncrona, pero en la ruta, la sintaxis async/await convierte este controlador de ruta en código asíncrono.
Por lo tanto, debe usar la declaración try...catch para detectar el error generado por la función de función underlyingFunction . Y pasa el error a la next función. express enrutará la solicitud al middleware del controlador de errores con ese error .
P.ej
app.ts :
import express from 'express'; import { ErrorRequestHandler } from 'express-serve-static-core'; export const createApp = (underlyingFunction) => { const app = express(); app.get('/my-endpoint', async (req, res, next) => { try { await underlyingFunction(); res.send({ success: true }); } catch (error) { next(error); } }); const errorHandler: ErrorRequestHandler = (error, req, res, next) => { console.error('Unhandled exception'); res.status(500).send({ message: 'Oh dear' }); }; app.use(errorHandler); return app; }; app.test.ts :
import request from 'supertest'; import { createApp } from './app'; describe('68923821', () => { test('error should be handled and return 500', async () => { const underlyingFunction = jest.fn().mockImplementation(() => { throw new Error('Something went wrong'); }); const app = createApp(underlyingFunction); const res = await request(app).get('/my-endpoint'); expect(res.status).toEqual(500); }); });resultado de la prueba:
PASS examples/68923821/app.test.ts (9.128 s) 68923821 ✓ error should be handled and return 500 (49 ms) console.error Unhandled exception 15 | 16 | const errorHandler: ErrorRequestHandler = (error, req, res, next) => { > 17 | console.error('Unhandled exception'); | ^ 18 | res.status(500).send({ message: 'Oh dear' }); 19 | }; 20 | at errorHandler (examples/68923821/app.ts:17:13) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 9.661 s