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

使用Jest测试Express+TS应用时Multer报undefined错误

TypeError: Cannot read properties of undefined (reading 'diskStorage')——测试Multer+Express+TypeScript应用的问题

问题场景

我开发了基于TypeScript的Express应用,用Multer处理文件上传,应用本身运行正常,但用Jest测试时触发错误:TypeError: Cannot read properties of undefined (reading 'diskStorage'),错误出在调用multer.diskStorage()的Multer配置模块中。

相关代码如下:

Multer配置模块

import multer from "multer";

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, "images/");
    },
    filename: function (req, file, cb) {
        const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
        cb(
            null,
            (
                file.fieldname +
                "-" +
                uniqueSuffix +
                "-" +
                file.originalname
            ).replace(/ /g, "_")
        );
    },
});

function filter(req: object, file: Express.Multer.File, cb: Function) {
    cb(null, file.mimetype === "image/jpg" || file.mimetype === "image/jpeg");
}

const postStorage = multer({
    storage: storage,
    fileFilter: filter,
    limits: {
        fileSize: 1024 * 1024, // max size in bytes
    },
});

export default postStorage;

路由使用代码

const router = express.Router();

router.get("/", getAll);
router.post(
    "/",
    postStorage.fields([
        { name: "main_image", maxCount: 1 },
        { name: "additional_images", maxCount: 5 },
    ]),
    RequestValidator(PostSchema, "body"),
    insert
);

export default router;

Jest测试代码

describe("do ", () => {
    describe("dodo", () => {
        it("dododo", async () => {
            await supertest(app).get("/").expect(200);
            return true;
        });
    });
});

解决方案

这个错误的核心是Jest测试环境中Multer模块的导入或解析出现问题,以下是几种可行的解决方法:

1. 修正Multer导入方式

将默认导入改为命名导入,避免Jest对ES模块默认导入的解析异常:

// 替换原import语句
import * as multer from "multer";

这种方式能确保获取完整的Multer模块对象,不会出现模块为undefined的情况。

2. 配置Jest兼容ES模块

如果项目使用ES模块,在jest.config.js或jest.config.ts中添加以下配置:

module.exports = {
  // 其他已有配置...
  transform: {
    "^.+\\.tsx?$": "ts-jest",
  },
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
  // 让Jest不忽略Multer模块的转换
  transformIgnorePatterns: ["<rootDir>/node_modules/(?!multer)/"],
};

transformIgnorePatterns设置会确保Multer被ts-jest正确转换,避免因模块格式不兼容导致的错误。

3. 模拟Multer模块(适用于无需测试文件上传逻辑的场景)

如果测试仅验证路由基础响应(比如示例中的GET请求),可以直接在测试中模拟Multer,跳过真实的文件上传逻辑:
在测试文件顶部添加:

jest.mock("multer", () => ({
  diskStorage: jest.fn(),
  __esModule: true,
  default: jest.fn(() => ({
    fields: jest.fn(() => (req, res, next) => next()),
  })),
}));

这个模拟会让Multer返回一个空中间件,不会触发真实的diskStorage调用,从而绕过错误。

4. 检查TypeScript配置

确保tsconfig.json的模块设置与Jest兼容:

{
  "compilerOptions": {
    "module": "CommonJS", // 若用ESNext需对应调整Jest配置
    "target": "ES6",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

esModuleInterop和allowSyntheticDefaultImports能帮助TypeScript正确处理CommonJS模块的默认导入,避免导入后模块为undefined。

内容的提问来源于stack exchange,提问作者Muhib Al Hasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:17:35