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

Jest测试Node.js+Prisma API时roomType未定义错误排查

Jest测试Node.js+Prisma房间创建API失败排查与解决

问题现象

使用Jest测试房间创建API时出现两个问题:

  1. 核心报错:TypeError: Cannot read properties of undefined (reading 'roomType')
  2. 测试超时:Exceeded timeout of 5000 ms for a test,且进程未正常退出
    但Postman调用该API完全正常。

相关代码

服务端创建接口代码

async function createData(req, res) {
    const newData = req.body

    const data = await prisma.room.create({
        data: {
            roomType: newData.roomType,
            roomImage: newData.roomImage,
            roomStatusId: newData.roomStatusId,
            roomCode: newData.roomCode,
            roomCapacityId: newData.roomCapacityId,
            category: newData.category,
            floor: newData.floor,
            i: newData.i,
            occupied_status: newData.occupied_status,
            overlook: newData.overlook,
            description: newData.description,
            bedSetup: newData.bedSetup,
            connecting: newData.connecting,
            rateCodeId: newData.rateCodeId
        }
    });

    if (!data) {
        return errorResponse(res, 'Error', '', 404);
    }

    return successResponse(
        res,
        `Data has been inserted successfully`,
        data,
        200,
    );
}

Jest测试代码

describe('POST /room', () => {
    it('Should create a new room', async () => {
        const newData = {
            roomType: "STANDARD",
            roomImage: "https://i.pravatar.cc/300",
            roomStatusId: 1,
            roomCode: 1,
            roomCapacityId: 1,
            category: "well",
            floor: 3,
            i: 2,
            occupied_status: true,
            overlook: "well",
            description: "kamar well",
            bedSetup: "well",
            connecting: "well",
            rateCodeId: 1
        };

        const response = await request(app)
            .post('/room')
            .send(newData);

        // Perform assertions
        expect(response.statusCode).toBe(200);
        expect(response.body).toHaveProperty('data');
        expect(response.body.data).toMatchObject(newData);
    });
});

完整错误日志

FAIL __tests__/apis/room.api.test.js (9.585 s)
  ● POST /room › Should create a new room

    TypeError: Cannot read properties of undefined (reading 'roomType')

      40 |     const data = await prisma.room.create({
      41 |         data: {
    > 42 |             roomType: newData.roomType,
         |                               ^
      43 |             roomImage: newData.roomImage,
      44 |             roomStatusId: newData.roomStatusId,
      45 |             roomCode: newData.roomCode,

      at roomType (src/services/room.service.js:42:31)
      at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)
      at next (node_modules/express/lib/router/route.js:144:13)
      at Route.dispatch (node_modules/express/lib/router/route.js:114:3)
      at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)
      at node_modules/express/lib/router/index.js:284:15
      at Function.process_params (node_modules/express/lib/router/index.js:346:12)
      at next (node_modules/express/lib/router/index.js:280:10)
      at Function.handle (node_modules/express/lib/router/index.js:175:3)
      at router (node_modules/express/lib/router/index.js:47:12)
      at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)
      at trim_prefix (node_modules/express/lib/router/index.js:328:13)
      at node_modules/express/lib/router/index.js:286:9
      at Function.process_params (node_modules/express/lib/router/index.js:346:12)
      at next (node_modules/express/lib/router/index.js:280:10)
      at expressInit (node_modules/express/lib/middleware/init.js:40:5)
      at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)
      at trim_prefix (node_modules/express/lib/router/index.js:328:13)
      at node_modules/express/lib/router/index.js:286:9
      at Function.process_params (node_modules/express/lib/router/index.js:346:12)
      at next (node_modules/express/lib/router/index.js:280:10)
      at query (node_modules/express/lib/middleware/query.js:45:5)
      at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)
      at trim_prefix (node_modules/express/lib/router/index.js:328:13)
      at node_modules/express/lib/router/index.js:286:9
      at Function.process_params (node_modules/express/lib/router/index.js:346:12)
      at next (node_modules/express/lib/router/index.js:280:10)
      at Function.handle (node_modules/express/lib/router/index.js:175:3)
      at Function.handle (node_modules/express/lib/application.js:181:10)
      at Server.app (node_modules/express/lib/express.js:39:9)

  ● POST /room › Should create a new room

    thrown: "Exceeded timeout of 5000 ms for a test.
    Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout."

      24 | });
      25 | describe('POST /room', () => {
    > 26 |     it('Should create a new room', async () => {
         |     ^
      27 |         const newData = {
      28 |             roomType: "STANDARD",
      29 |             roomImage: "https://i.pravatar.cc/300",

      at it (__tests__/apis/room.api.test.js:26:5)
      at Object.describe (__tests__/apis/room.api.test.js:25:1)

A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
Test Suites: 1 failed, 2 passed, 3 total
Tests:       1 failed, 8 passed, 9 total
Snapshots:   0 total
Time:        10.968 s
Ran all test suites.

问题原因

  1. Express未配置JSON解析中间件:服务端代码依赖req.body获取请求数据,但Express默认不会自动解析JSON格式的请求体。Postman会自动设置Content-Type: application/json并发送正确格式数据,而测试环境中如果app实例未挂载express.json()中间件,req.body会是undefined,导致读取newData.roomType时报错。
  2. Prisma客户端未正确断开连接:测试结束后未关闭Prisma客户端连接,导致进程无法正常退出,触发Jest超时。

解决步骤

1. 为Express应用添加JSON解析中间件

在你的Express主入口文件中,添加以下代码(必须在挂载路由之前):

const express = require('express');
const app = express();

// 解析JSON格式的请求体
app.use(express.json());

// 挂载房间相关路由
app.use('/room', roomRouter);

module.exports = app;

2. 确保测试请求发送正确格式(可选但推荐)

虽然supertest的.send()方法默认会设置Content-Type: application/json,但显式指定可以避免潜在问题:

const response = await request(app)
    .post('/room')
    .set('Content-Type', 'application/json')
    .send(newData);

3. 修复测试超时与资源泄漏

在测试文件末尾添加Prisma客户端的清理逻辑,确保测试完成后断开连接:

const prisma = require('../../src/prisma/client'); // 根据你的路径调整

describe('POST /room', () => {
    // ... 测试用例

    afterAll(async () => {
        // 测试结束后断开Prisma连接
        await prisma.$disconnect();
    });
});

如果仍有超时问题,可以临时调整测试用例的超时时间:

it('Should create a new room', async () => {
    // ... 测试代码
}, 10000); // 设置10秒超时

4. 可选:添加请求体校验增强鲁棒性

在服务端接口中添加基础校验,防止req.body为空时崩溃:

async function createData(req, res) {
    const newData = req.body;

    // 校验必填字段
    if (!newData || !newData.roomType) {
        return errorResponse(res, '缺少必填字段roomType', '', 400);
    }

    const data = await prisma.room.create({
        data: {
            // ... 字段映射
        }
    });

    // ... 后续响应逻辑
}

内容的提问来源于stack exchange,提问作者Nabil Mudzaki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:44:52