Error: <spyOnProperty> : function is not declared configurable

12,028

Solution 1

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.

  1. You don't create an object nor provide it to spyOnProperty.

  2. 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();
});

Solution 2

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.

Share:
12,028
konrado
Author by

konrado

Updated on June 11, 2022

Comments

  • konrado
    konrado almost 2 years

    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)
    }