简体   繁体   中英

Error: supportsScrollBehavior is not declared configurable

I am trying to spy on a function supportsScrollBehavior of angular platform service like below -

import * as platform from '@angular/cdk/platform';
  describe('Supporting Scroll Behaviour', () => {
    beforeEach(() => {
      const funcSpy = jasmine.createSpy('supportsScrollBehavior').and.returnValue(true);
      spyOnProperty(platform, 'supportsScrollBehavior', 'get').and.returnValue(funcSpy);
    });
  });
});

But it is giving me an error like below -

Error: supportsScrollBehavior is not declared configurable

In angular 8 it was working fine, but in Angular 9 version it is giving this error. Any pointers will be really helpful.

It is not possible anymore to spy on individually exported functions. https://github.com/jasmine/jasmine/issues/1414

There are some workarounds that might work, but there isn't a "works for all" solution.

Quoting from above link:

Actually setting "module": "commonjs" in tsconfig.json for tests fixes this issue and you can use spyOn again.

For me, this didn't work. Jasmine needs a place to put the spy in, so I created a Wrapper class so that the spy is installed on that class instead of the module.

import { supportsScrollBehavior as cdkSupportsScrollBehavior} from '@angular/cdk/platform';

export class CdkWrapper {
    public static supportsScrollBehavior(...args) {
        return cdkSupportsScrollBehavior(...args);
    }
}

Which you use like this in the spec file:

spyOn(CdkWrapper , 'supportsScrollBehavior').and.returnValue(true);

Remember to also use that wrapper in the component you are testing!

CdkWrapper.supportsScrollBehavior()

So this is telling you that the property is not 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 spy on the imported object function.

// 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'

Then you can apply this solution on the writable error that usually also follows - but the prop needs to be configurable and writable (for the spy to apply)

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
    get: () => {}, // or whatever makes sense
    value: () => {}, // or whatever makes sense
  });
});

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM