Reputation: 235
I had working jasmine tests with webpack 3. Now I try to use it with webpack 4 but have some problem with it.
Firstly I had problem with spyOn function.
Error: : myFunction is not declared writable or has no setter
I found some articles about some workaround for this problem: spy-on-getter-and-setter
I changed spyOn to spyOnProperty but with no luck. Now I have problem with
> Error: : myFunction is not declared configurable
My code is written in js and looks like this:
import * as FocusServiceSpy from '../focus/FocusService';
describe('#onLinkClick', function() {
it('should call myFunction', () => {
spyOnProperty(FocusServiceSpy, 'myFunction', 'get');
expect(FocusServiceSpy.myFunction).toHaveBeenCalled();
});
}
Do you know what could be a problem with this?
UPDATE 1:
I should be more descriptive. I would like to create spy on function of the FocusService. This service has only one method called myFunction. Only thing I want to achieve is to ensure that this method will be called.
Now I changed it to sth like this and have error:
>TypeError: Object is not a constructor (evaluating 'new FocusService()') (line 180)
describe('#onLinkClick', function() {
const FocusService = require('../focus/FocusService');
it('should call myFunction', () => {
const service = new FocusService();
spyOnProperty(service, 'myFunction').and.callThrough();
... (do some action)
expect(service.myFunction).toHaveBeenCalled();
});
}
FocusService looks like this:
export function myFunction(arg) {
... (do some action)
}
Upvotes: 19
Views: 31172
Reputation: 109
add configure({ safeDescriptors: false });
after the imports in Classdefinition file and it works with the properties
Upvotes: 0
Reputation: 26190
In your unit test, I can see several problems. First you need to understand that spyOnProperty
installs a spy
on a property onto an existing object but it does not invoke the getter
itself.
You don't create an object nor provide it to spyOnProperty
.
You invoke spyOnProperty
with a function name instead of a property
name.
Your test could be structured as follows:
it('should call myFunction', () => {
// given
const service = new FocusService();
const spy = spyOnProperty(service , 'myProperty', 'get').and.callThrough();
// when
const myProperty = service.myProperty;
// then
expect(myProperty).toBe(<expected value>);
expect(spy).toHaveBeenCalled();
});
Upvotes: 7
Reputation: 455
With the newer version of Jasmine, the mutation of spies are not allowed and throws the above error for the member of the spy you are trying to modify.
Altering the definition of a spy's property isn't recommended as Jasmine explicitly disallows the members to be configurable.
Add the following code to your entry test file if you don't want this limitation to be forced upon you.
const defineProperty = Object.defineProperty;
Object.defineProperty = (o, p, c) => defineProperty(o, p, Object.assign({}, c ?? {}, { configurable: true }));
The code above forces every property, that is defined during the test run, to be marked as configurable.
Upvotes: 1
Reputation: 5352
I have experienced the same problem when I tried to upgrade project from Angular 8 to 9, there is no answer that I could find on Google, however I figured out a way how to solve it in my project.
In tsconfig.json
, change target
to es5
.
Example:
{
"compilerOptions": {
...
"target": "es5",
...
}
}
That's it! Hope this could help someone is trying to find the solution.
Upvotes: 1