Jest测试Express请求体验证中间件时出现TypeError问题求助
Express中间件Jest测试报错:Cannot read properties of undefined (reading 'json')
我写了一个验证请求体的Express中间件,代码如下:
export default function validateReqBodyMiddleware(req: Request, res: Response, next: NextFunction) { const { name, email }: RequestBody = req.body; let errors: iError[] = []; if (!validator.isEmail(email.trim())) errors.push({error: "invalid email", invalidField: "email"}); if (validator.isEmpty(name.trim())) errors.push({error: "empty name", invalidField: "name"}); if (errors.length) return res.status(Status.BadRequest).json(errors); next(); }
对应的Jest单元测试代码:
import validateRequestBody from "../../middlewares/validateRequestBody.middleware"; import { Request, Response, NextFunction } from "express"; describe("validateRequestBody middleware", () => { let mockRequest: Partial<Request>; let mockResponse: Partial<Response>; let nextFunction: NextFunction = jest.fn(); beforeEach(() => { mockRequest = {}; mockResponse = { status: jest.fn(), json: jest.fn(), }; }); test("wrong email format", async () => { const expectedResponse = [{ error: "invalid email", invalidField: "email" }]; mockRequest = { body: { name: "John Doe", email: "test" } } validateRequestBody( mockRequest as Request, mockResponse as Response, nextFunction ); expect(mockResponse.status).toBeCalledWith(400); expect(mockResponse.json).toBeCalledWith(expectedResponse); }); });
测试时出现如下报错:
FAIL src/tests/unitTests/test_validateRequestBody.middleware.test.ts validateRequestBody middleware ✕ wrong email format (2 ms) ● validateRequestBody middleware › wrong email format TypeError: Cannot read properties of undefined (reading 'json') 23 | if (validator.isEmpty(name.trim())) errors.push({error: "empty name", invalidField: "name"}); 24 | > 25 | if (errors.length) return res.status(Status.BadRequest).json(errors); | ^ 26 | next(); 27 | } at validateRequestBody (src/middlewares/validateRequestBody.middleware.ts:25:58) at Object.<anonymous> (src/tests/unitTests/test_validateRequestBody.middleware.test.ts:27:24) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 1.216 s, estimated 2 s Ran all test suites.
我发现单独调用res.status()或res.json()时测试能通过,但链式调用就报错,求解决方法。
解决方案
问题根源在于你mock的status方法默认返回undefined,而Express的res.status()实际会返回响应对象本身,这样才能支持链式调用json()。
修改测试代码中mockResponse的status方法,让它返回自身:
mockResponse = { status: jest.fn().mockReturnThis(), // 关键修改:返回mockResponse自身 json: jest.fn(), };
修改后,当中间件调用res.status(400)时,会返回mockResponse对象,接着调用.json(errors)就能正常访问到json方法,测试就能通过了。
你还可以补充测试用例验证验证通过时的逻辑:
test("valid request body calls next", () => { mockRequest = { body: { name: "John Doe", email: "john@example.com" } }; validateRequestBody( mockRequest as Request, mockResponse as Response, nextFunction ); expect(nextFunction).toHaveBeenCalled(); expect(mockResponse.status).not.toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者Guilherme Massoqueto
相关产品推荐
相关产品推荐

