I aimed to conduct a unit test for a function, applyDiscount(), while avoiding reliance on external sources. To achieve this, I employed a mock function. Please help me to find out this error : "TypeError: Cannot assign to read only property 'getCustomerSync' of object '[object Module]'". Here's my code :

db.js file:
----------
const getCustomerSync = (id) => { // synchronous function
    console.log('Reading a customer from MongoDB...');
    return { id: id, points: 11 };
}
const getCustomer = (id) => { // asynchronous function
    return new Promise((resolve, reject) => {
      console.log('Reading a customer from MongoDB...');
      resolve({ id: id, points: 11 });
    });
}
export { getCustomer, getCustomerSync };

lib.js file:
---------
import * as db from "./db.js";
const applyDiscount = (order) => {
  const customer = db.getCustomerSync(order.customerId); // fake external ressource

  if (customer.points > 10)
    order.totalPrice *= 0.9; // 10% discount
}

lib.test.js file:
---------------
describe("applyDiscount", () => {
    it("should apply 10% discount if customer has more than 10 points", () => {
        const mockFunction = jest.fn();
        db.getCustomerSync = mockFunction.mockReturnValue({ id: 1, points: 20 });

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

package.json file :
-------------------
{
  "name": "testing-demo",
  "version": "1.0.0",
  "description": "Automates unit test",
  "main": "db.js",
  "type": "module",
  "scripts": {
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "jest": "^29.7.0"
  }
}
1

There are 1 best solutions below

1
On

The problem is probably this line:

db.getCustomerSync = mockFunction.mockReturnValue({ id: 1, points: 20 });

You cannot reassign properties on ES imports as they are read-only, as indicated in the error message.

You can mock the named export using Jest however:

jest.mock("./db,js", () => ({
  ...jest.requireActual("./db.js"),
  getCustomerSync: jest.fn().mockReturnValue({ id: 1, points: 20 })
}))

You can see other examples in answers to a similar question here.