You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:50:24