In an upgrade to Angular 9 (from 8.1) and Typescript 3.7 (from <3.6), I have encountered an issue with spyOnProperty
My service looks like:
class Backend {
public get baseURL(): string {
return 'http://baseurl.com/';
}
}
My test that worked before the upgrade would spyOnProperty
spyOnProperty(backend, 'baseURL', 'get').and.returnValue('http://new');
However, I am now getting this error:
Error: <spyOnProperty> : baseURL is not declared configurable
Usage: spyOnProperty(<object>, <propName>, [accessType])
I know that I need to Object.defineProperty
as configurable: true
, as when stepping through Jasmine I see it fails at:
if (!descriptor.configurable) {
throw new Error(
getErrorMsg(propertyName + ' is not declared configurable')
);
}
And descriptor
is created by descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
So in Javascript I would want to:
Object.defineProperty(backend.prototpye, 'baseURL', {value: 'http://new', configurable: true});
To ensure that this property could be spied on.
However, my question is how do I apply the same configurable with Typescript. I have tried to run Object.defineProperty
again but I get an error defineproperty Cannot redefine property
, which makes sense as to why the check is there in the first place.
I tried using the suggested configurable
decorator defined here :
function configurable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
};
}
But this does not work, also to note that when I put a breakpoint inside the above method, the descriptor.configurable
is actually already set to true
before assigning the value
. So I am not sure what is actually causing the original error in the tests.
I missed some additional information about creating my tests. To create an instance of the injected services I am using, ts-mockito to create an instance()
of each class.
I think it was this call to instance()
that was creating properties as not configurable.
Effectively:
service = new Service(instance(new Backend));
Changed to:
service = new Service(new Backend);
Resolves the issue
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.