Node.js/TypeScript单元测试报错:期望返回201实际得到200
单元测试断言201状态码失败的排查与解决
问题描述
编写了名为should return 201 response code的单元测试,但测试失败,提示:
Expected: 201
Received: 200
Postman手动调用接口时能正常返回201 Created状态码,即使简化控制器代码后,测试仍无法通过。
相关代码
原始控制器代码(orderController.ts)
import { Request, Response } from "express"; import { Orders } from "../models/orders"; const createOrder = async ( req: Request, res: Response) => { try { const newOrder = await Orders.create(req.body) res.status(201).json({ status: 'success', data: { order: newOrder, } }) } catch (error) { res.status(400).json({ status: 'fail', message: error, }); } }
测试代码(orderController.test.ts)
import { Request, Response } from "express"; import { createOrder } from "../../controllers/orderController"; import { Orders } from "../../models/orders"; import httpMocks from 'node-mocks-http' import newOrder from '../mock-data/new-order.json' Orders.create = jest.fn() let req: Request, res: Response beforeEach(() => { req = httpMocks.createRequest() res = httpMocks.createResponse() }) describe("createOrder", () => { it("should have a createOrder function", () => { expect(typeof createOrder).toBe("function"); }) it("should call Orders.create", () => { req.body = newOrder createOrder(req, res) expect(Orders.create).toBeCalledWith(newOrder) }) it("should return 201 response code", () => { req.body = newOrder; createOrder(req, res); expect(res.statusCode).toBe(201); }) })
终端报错信息
✕ should return 201 response code (1 ms) ● createOrder › should return 201 response code expect(received).toBe(expected) // Object.is equality Expected: 201 Received: 200
简化后的控制器代码(测试仍不通过)
const createOrder = async (req: Request, res: Response) => { const newOrder = await Orders.create(req.body) res.status(201) }
解决思路
问题核心是异步函数未被正确等待:
createOrder是异步函数,调用后会返回Promise。测试中直接同步执行createOrder(req, res),此时函数内部的await Orders.create还未完成,res.status(201)还没执行,就已经开始断言状态码,所以拿到的是响应对象的默认值200。
修正方案
方案1:使用async/await等待异步函数完成
修改测试用例:
it("should return 201 response code", async () => { req.body = newOrder; await createOrder(req, res); // 等待异步逻辑执行完毕 expect(res.statusCode).toBe(201); })
方案2:使用done回调处理异步
it("should return 201 response code", (done) => { req.body = newOrder; createOrder(req, res).then(() => { expect(res.statusCode).toBe(201); done(); // 通知测试异步逻辑已完成 }); })
可选优化:显式Mock Orders.create的返回值
为了让测试更严谨,建议给Mock的Orders.create指定resolved的返回值:
Orders.create = jest.fn().mockResolvedValue(newOrder);
内容的提问来源于stack exchange,提问作者track_p54skate
相关产品推荐
相关产品推荐

