Express接口测试异常:重复商品用例无法获取422状态码
问题:重复商品订单测试用例无法正确断言状态码
问题场景
我在测试一个Express + TypeScript的结账接口,其中检测重复商品的测试用例明明进入了catch块并返回了错误消息,但测试里始终拿不到响应状态码,output.status一直是undefined。移除状态码断言后测试能通过,但其他测试用例(比如无效CPF)却能正常获取状态码。
接口代码
import express, { Request, Response } from "express"; import { validate } from "./validator"; import pgp from "pg-promise"; const app = express(); app.use(express.json()); app.post("/checkout", async function (req: Request, res: Response) { const connection = pgp()("postgres://postgres:dev123@localhost:5432/tdd-app"); try { const isValid = validate(req.body.cpf); if (!isValid) throw new Error("Invalid cpf"); const output: Output = { total: 0, }; const items: number[] = []; if (req.body.items) { for (const item of req.body.items) { if (item.quantity <= 0) throw new Error("Invalid quantity"); if (items.includes(item.idProduct)) throw new Error("Duplicated item"); const [productData] = await connection.query( "SELECT * FROM cccat10.product WHERE id_product = $1", item.idProduct ); output.total += parseFloat(productData.price) * item.quantity; items.push(item.idProduct); } } if (req.body.coupon) { const [couponData] = await connection.query( "SELECT * FROM cccat10.coupon WHERE code = $1", [req.body.coupon] ); if (couponData.expire_date.getTime() >= new Date().getTime()) { const percentage = parseFloat(couponData.percentage); output.total -= (output.total * percentage) / 100; } } res.json(output); } catch (e: any) { res.status(422).json({ message: e.message, }); } finally { await connection.$pool.end(); } }); type Output = { total: number; message?: string; }; app.listen(3000);
有问题的测试用例
test("Shouldnt create an order with duplicated item", async function () { const input = { cpf: "684.053.160-00", items: [ { idProduct: 1, quantity: 1 }, { idProduct: 1, quantity: 1 }, ], }; const response = await axios.post("http://localhost:3000/checkout", input); const output = response.data; expect(output.status).toBe(422); expect(output.message).toBe("Duplicated item"); });
正常工作的测试用例(对比参考)
test("Shouldnt accept an order with an invalid cpf ", async function () { const input = { cpf: "406.302.170-27", }; const response = await axios.post("http://localhost:3000/checkout", input); const output = response.data; expect(response.status).toBe(422); expect(output.message).toBe("Invalid cpf"); });
问题修复方案
问题根源在于测试用例的断言对象错误:
- HTTP响应状态码是axios返回的**
response对象**的属性,不是响应体(output = response.data)的属性 - 你在有问题的测试里错误地断言了
output.status,正确做法是和正常测试用例一样,断言response.status
修改后的测试用例:
test("Shouldnt create an order with duplicated item", async function () { const input = { cpf: "684.053.160-00", items: [ { idProduct: 1, quantity: 1 }, { idProduct: 1, quantity: 1 }, ], }; const response = await axios.post("http://localhost:3000/checkout", input); const output = response.data; expect(response.status).toBe(422); // 改为断言response对象的status属性 expect(output.message).toBe("Duplicated item"); });
补充说明:
当接口返回422状态码时,axios的response对象会包含status字段,但你在catch块里返回的响应体只有message字段,并没有status,所以之前的output.status自然是undefined。
内容的提问来源于stack exchange,提问作者Louis
相关产品推荐
相关产品推荐

