0

publicEncrypt is not declared writable or has no setter

 beforeEach(fakeAsync(() => {
        spyOn(CryptoBrowserify, 'publicEncrypt').and.returnValue(Buffer.from('ENCRYPT', 'utf8'));
        
      }));

Error: <spyOn> : publicEncrypt is not declared writable or has no setter
    Usage: spyOn(<object>, <methodName>)
    Error: <spyOn> : publicEncrypt is not declared writable or has no setter
    Usage: spyOn(<object>, <methodName>)
  • It seems like you want to `spyOn` an imported library function. It is not possible to do that anymore with the changes/updates to TypeScript. I have found this to be the best method in spying on imported libraries: https://stackoverflow.com/questions/60259259/error-supportsscrollbehavior-is-not-declared-configurable/62935131#62935131. Read the Github thread as well. – AliF50 Jun 13 '22 at 16:30
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Jun 14 '22 at 06:42
  • @AliF50 Thank you, working fine with Wrapper class, did you get a chance to write test case for wrapper class? we need to cover 100%, export class CryptoBrowserifyWrapper { public static publicEncrypt(...args) { return publicEncryptLocal(...args); } } – Hari Krishna Jun 14 '22 at 07:38
  • I am not sure how to test the wrapper class, I personally did not test it. Show your boss this tweet: https://twitter.com/BenLesh/status/912487170371284994 ;). – AliF50 Jun 14 '22 at 12:56

1 Answers1

0

So this is telling you that the property is not writable.

You can work around this by overriding the property descriptor for the duration of your test

Note that you can only do this if the property is configurable.

I have found that in Angular if you do the below prop descriptors come as non-configurable so you will not be able to apply the solution

// this will cause prop descriptors to come as non-configurable
import from 'zone.js'

So in your test.ts do this instead

// this will cause prop descriptors to come as configurable
import from 'zone.js/dist/zone'
import from 'zone.js/dist/zone-testing'
import * as someNsObj from 'external/lib';

// get the current descriptor
const originalDesc = Object.getOwnPropertyDescriptor(someNsObj, 'targetFunction');

// replace with a writable prop
beforeAll(() => {
  Object.defineProperty(someNsObj, 'targetFunction', {
    enumerable: true,
    configurable: true,
    writable: true, // this is what makes the difference
    value: () => {}, // or whatever makes sense
  });
});

// restore the original descriptor
afterAll(() => {
  Object.defineProperty(someNsObj, 'targetFunction', originalDesc);
});
GKA
  • 1,230
  • 1
  • 15
  • 15