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
相关产品推荐
相关产品推荐

