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

Jest+Node.js报错:无法赋值给只读属性'getCustomerSync'求助

解决ES模块下Jest Mock报错:TypeError: Cannot assign to read only property

问题原因

你的项目启用了ES模块(package.json中type: "module"),ES模块的导出是只读绑定,无法直接通过赋值修改导出的函数(比如db.getCustomerSync = mockFunction),这就是报错的核心原因。

解决方案

方案1:模拟整个db模块

在测试文件顶部用jest.mock自动模拟整个db.js模块,然后直接指定mock函数的返回值:

// lib.test.js
import * as db from "./db.js";
import { applyDiscount } from "./lib.js";

// 自动模拟db模块的所有导出
jest.mock("./db.js");

describe("applyDiscount", () => {
    it("should apply 10% discount if customer has more than 10 points", () => {
        // 设定getCustomerSync的mock返回值
        db.getCustomerSync.mockReturnValue({ id: 1, points: 20 });

        const order = { customerId: 1, totalPrice: 10 };
        applyDiscount(order);
        
        expect(order.totalPrice).toBe(9);
        // 可选:验证mock函数是否被正确调用
        expect(db.getCustomerSync).toHaveBeenCalledWith(1);
    });
});

方案2:单独mock单个函数(使用jest.spyOn)

如果只想mockgetCustomerSync而保留其他导出的原始实现,可以用jest.spyOn:

// lib.test.js
import * as db from "./db.js";
import { applyDiscount } from "./lib.js";

describe("applyDiscount", () => {
    it("should apply 10% discount if customer has more than 10 points", () => {
        // 监听getCustomerSync并替换为mock函数
        const mockFn = jest.spyOn(db, "getCustomerSync")
            .mockReturnValue({ id: 1, points: 20 });

        const order = { customerId: 1, totalPrice: 10 };
        applyDiscount(order);
        
        expect(order.totalPrice).toBe(9);
        expect(mockFn).toHaveBeenCalledWith(1);

        // 测试结束后恢复原函数,避免影响其他测试用例
        mockFn.mockRestore();
    });
});

注意事项

  • 确保你的Jest测试脚本配置正确(已启用--experimental-vm-modules),你的package.json中的test命令已经符合要求:
    "scripts": {
      "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:45:11