'Sails.js: Jest spyOn results in TypeError: Cannot assign to read only property

I'm trying to mock the implementation of a function call using Jest's spyOn:

await sails.helpers.models.test.randomFn.with({ ... });
const randomFnSpy = jest.spyOn(sails.helpers.models.test.randomFn, 'with');
randomFnSpy.mockImplementation(() => {});

Error:

TypeError: Cannot assign to read only property 'with' of function 'function runFn(_argins, _explicitCbMaybe, _metadata){

I tried setting the property as configurable and writable :

Object.defineProperty(
  sails.helpers.models.test.randomFn, 
  'with', 
  { configurable: true, writable: true }
);

Error:

TypeError: Cannot redefine property: with at Function.defineProperty ()



Solution 1:[1]

What worked to mock helpers for me:

Sails internally uses machine which does the following:

Object.defineProperty(wetMachine, 'with', {
    enumerable: false,
    configurable: false,
    writable: false,
    value: arginStyle === 'named' ? wetMachine : wetMachine.customize({
      arginStyle: 'named',
      execStyle: execStyle,
      extraArginsTactic: extraArginsTactic,
      extraCallbacksTactic: extraCallbacksTactic,
      arginValidationTactic: arginValidationTactic,
      resultValidationTactic: resultValidationTactic,
      finalAfterExec: finalAfterExec,
      defaultMeta: defaultMeta,
      defaultArgins: defaultArgins,
      // Note there is no reason to pass through `implementationSniffingTactic`
      // here, since it would have already applied now (it applies at build-time.)
    })
  });

Instead of spying on with, mocking the helper's fn did the trick:

jest.mock('../../../../../api/helpers/models/test/random-fn', () => ({ fn: () => {} }));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Majed Badawi