Reputation: 2361
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.
Upvotes: 4
Views: 4834
Reputation: 1356
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);
});
Upvotes: 0
Reputation: 141
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()
Upvotes: 4