The configuration of the property has not been declared (Error: <spyOnProperty>)

Imagine having a MenuComponent

@Component({
  selector: 'cg-menu',
  templateUrl: './menu.component.html',
  styleUrls: [ './menu.component.scss' ]
})
export class MenuComponent implements OnInit {
  menu: MenuItem[];

  isLoggedIn$ = this.authStateService.isLoggedIn.pipe(untilDestroyed(this));

  constructor(private readonly authStateService: AuthStateService,
              private readonly router: Router) {
  }

  ngOnInit() {
    this.authStateService
      .state
      .pipe(
        untilDestroyed(this),
        ...some logic...
      .subscribe();
  }

  ...some logic...
}

Now, consider a AuthStateService

@Injectable({ providedIn: 'root' })
export class AuthStateService {
  private readonly state$: Observable<AuthState | null>;
  private readonly isLoggedIn$: Observable<boolean | null>;

  constructor(private readonly sessionManager: SessionManagerService) {

    this.state$ = this.stateTrigger$
      .pipe(
        ...some logic...
        shareReplay(1));

    this.isLoggedIn$ = this.stateTrigger$
      .pipe(
        map(state => state !== null),
        shareReplay(1));
  }

  get state(): Observable<AuthState> {
    return this.state$;
  }

  get isLoggedIn(): Observable<boolean> {
    return this.isLoggedIn$;
  }

  ...some logic...
}

While attempting to execute this code, I encountered an error triggered by Karma.

describe('MenuComponent', () => {
  let component: MenuComponent;
  let fixture: ComponentFixture<MenuComponent>;

  let authStateServiceSpy;

  beforeEach(async(() => {
    authStateServiceSpy = jasmine.createSpyObj(
      'AuthStateService',
      {},
      {
        state: of(null),
        isLoggedIn: of(false)
      });

    TestBed.configureTestingModule({
      declarations: [ MenuComponent ],
      imports: [ RouterTestingModule ],
      providers: [
        { provide: AuthStateService, useValue: authStateServiceSpy }
      ],
      schemas: [ NO_ERRORS_SCHEMA ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MenuComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should generate correct menu (expert)', () => {
    // The problem is here
    spyOnProperty(authStateServiceSpy, 'state', 'get').and.callFake(() => of(stateMock));

    expect(component.menu).toEqual([
      ...something...
    ]);
  });
});

The specific error message reads as follows:

Error: <spyOnProperty> : state is not declared configurable
    Usage: spyOnProperty(<object>, <propName>, [accessType])
    Error: <spyOnProperty> : state is not declared configurable
    Usage: spyOnProperty(<object>, <propName>, [accessType])
        at <Jasmine>
        at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/modules/structure/components/menu/menu.component.spec.ts:55:5)
        at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
        at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:292:1)
        at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:363:1)
        at Zone.run (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:123:1)
        at runInTestZone (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:545:1)
        at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:560:1)

Do you have any insights on what might be causing this issue? Thank you for your assistance.

Answer №1

Perhaps the issue arises because AuthStateService's state is implemented as a getter in the class, while your mock defines it as a regular property. To resolve this, make sure to declare it as a getter in your mock as well.

The problem may be attributed to the use of createSpyObj alongside spyOnProperty, especially when attempting to spy on a non-existent getter.

Upon reviewing your code, it appears that utilizing createSpyObj serves no particular purpose in this scenario. Adjusting your approach as follows could potentially solve the issue:

// ...

authStateServiceMock = {
    get state() { return of(null) },
    get isLoggedIn() { return of(false) },
};

// ...

spyOnProperty(authStateServiceMock, 'state', 'get').and.callFake(() => of(stateMock));

expect(component.menu).toEqual([
    ...something...
]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

rxjs subscriptions in Angular

When setting up a subscription in Angular, I am declaring it as follows: counterSubscription: Subscription However, an error is being thrown stating: Property 'counterSubscription' has no initializer and is not definitely assigned in the const ...

The functionality of the System JS map is not functioning properly

Despite the challenges I face with System.js, I find it to be a valuable tool that I prefer over alternatives. This is my current System.js configuration: System.config({ packages: { app: { format: 'register' ...

Thorough exploration of a collection of varied, categorized items

My goal is to have TypeScript ensure that all cases are covered when mapping over a union like this: type Union = { type: 'A', a: string } | { type: 'B', b: number } The handler for the Union: const handle = (u: Union): string = ...

Preact: occasional occurrence of a blank page after refreshing

Starting out with Preact & TypeScript, I decided to kickstart my project using the parcel-preact-typescript-boilerplate. Initially, everything seemed to be working smoothly. However, I noticed that occasionally, especially on reload or initial page lo ...

ASP.NET is being used to host an angular application, but the deployUrl feature is

I have a .NET 6.0 ASP.NET application where I've set up a route /ngxapp to serve my Angular 13 application. The Angular app is stored in the wwwroot/ngxapp folder, as shown below. I've been using this code for years to deliver the Angular app: ...

What could be causing my Ionic button to not initialize in the expected state while using ngIf with a boolean property connected to an Ionic checkbox?

I'm currently in the process of setting up a list of ingredients with checkboxes and conditional buttons, but I'm facing some challenges with the default state. Ideally, I only want the button to be visible when the checkbox is unchecked so that ...

Binding an ID to an <ion-textarea> in Ionic 3

Can an ID be assigned to an ion-textarea? For example: <ion-textarea placeholder="Enter your thoughts" id="thoughtsBox"></ion-textarea> Thank you very much ...

Deduce the generic types of conditional return based on object property

My goal is to determine the generic type of Model for each property. Currently, everything is displaying as unknown[] instead of the desired types outlined in the comments below. playground class Model<T> { x?: T } type ArgumentType<T> = T ...

The container is not adjusting to the screen size correctly and the flex-direction: row is not functioning as

Struggling with setting up a basic layout in Angular for my application. While I have experience with Angular, the actual HTML/CSS design is new to me. No matter what I try, I can't seem to get this container to take up the whole screen width. Variou ...

The upcoming developer manages to execute the program successfully, however, it continues to load indefinitely

Executing the command yarn dev consistently runs successfully in my VS Code terminal: $ yarn dev yarn run v1.22.19 warning ..\..\..\..\package.json: No license field $ next dev ready - started server on 0.0.0.0:3000, url: http://localho ...

Fetching Data Using Asynchronous API Calls

My goal is to retrieve all results consistently from the API, but I am encountering varying outcomes. The for loop seems to be skipping some requests and returning a random number of records. Can anyone provide assistance? I have experimented with using t ...

The variable 'BlogPost' has already been declared within the block scope and cannot be redeclared

When working with Typescript and NextJS, I encountered the following Typescript errors in both my api.tsx and blogPost.tsx files: Error: Cannot redeclare block-scoped variable 'BlogPost'.ts(2451) api.tsx(3,7): 'BlogPost' was also dec ...

Using TypeScript with AWS Lambda: To package imports or not to package? Alternatively: Error in Runtime.ImportModule: Module '@aws-sdk/...' not found

I have been working with the code in my lambda.ts file, attempting to execute it on an AWS Lambda: import 'aws-sdk' import { /* bunch of stuff... */ } from "@aws-sdk/client-cloudwatch-logs"; import {Context, APIGatewayProxyResult} from ...

Simple steps to make an Angular Material mat-card expand to full screen

Currently, my goal is to create a portal-style page layout using Angular Material. This layout will feature a grid of cards where each card can be expanded to take up the majority of the visible page, covering all other cards that are not in focus. The car ...

An error occurs in TypeScript when attempting to reduce a loop on an array

My array consists of objects structured like this type AnyType = { name: 'A' | 'B' | 'C'; isAny:boolean; }; const myArray :AnyType[] =[ {name:'A',isAny:true}, {name:'B',isAny:false}, ] I am trying ...

Save the reference URL of an image in Firestore by uploading the image

Here is my StackBlitz link for reference: https://stackblitz.com/edit/upload-image-ref-firestore?embed=1&file=src/app/ app.component.html I am currently utilizing AngularFire2 to upload images and I am curious about how I can store the reference of th ...

Calling a typed function with conditional types in Typescript from within another function

In my attempt to create a conditional-type function, I stumbled upon this question on Stack Overflow. Unfortunately, it seems that the approach doesn't work well with default values (regardless of where the default value is placed). Following the advi ...

Error SCRIPT1002 was encountered in the vendor.js file while using Angular 8 on Internet Explorer 11

Having trouble getting Angular to function properly in IE 11. I've tried all the solutions I could find online. The errors I'm encountering are as follows: SCRIPT1002: Syntax error File: vendor.js, Line: 110874, Column: 40 At line 110874 args[ ...

Switching from dark mode to light mode when reloading or navigating to a new page

Hello everyone. I've successfully implemented a dark mode toggle on my website, but I'm facing an issue where the mode resets whenever I navigate to a new page or refresh the current page. Can anyone help me figure out how to prevent this from ...

Having trouble utilizing yarn to import Mapbox into TypeScript

My process involves using the command: yarn add --dev @types/mapbox-gl @types/geojson This successfully adds mapbox and geojson to my project. I can see them when attempting to import mapboxgl. Next, I create something similar to this: import * as L ...