Search code examples
angularjestjsangular-standalone-components

jest ReferenceError: Cannot access 'BsNavbarDropdownComponent' before initialization


I'm trying to convert my angular app (NX monorepo) to use standalone components. However when doing so, my Jest unit tests stop working and give the following error:

ReferenceError: Cannot access 'BsNavbarDropdownComponent' before initialization

After a lot of troubleshooting it seems to boil down to the following:

app.component.ts

import { Component } from '@angular/core';
import { BsNavbarModule } from '@mintplayer/ng-bootstrap/navbar';
// import { BsNavbarModule } from './navbar/navbar.module';

@Component({
  selector: 'video-player-root',
  template: `<h1>ng-video-player</h1>`,
  standalone: true,
  imports: [BsNavbarModule]
})
export class AppComponent {}

app.component.spec.ts

import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      declarations: [],
      providers: []
    }).compileComponents();
  });

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});

I copied over the entire BsNavbarModule from my library to the application. Here's a minimal reproduction. When the following is used

import { BsNavbarModule } from '@mintplayer/ng-bootstrap/navbar';

the unit test fails with

ReferenceError: Cannot access 'BsNavbarDropdownComponent' before initialization

However when the exact same, in-app module is used

import { BsNavbarModule } from './navbar/navbar.module';

the test runs perfectly fine. Why is that? How do I fix this? I've seen tons of questions with similar error message, but not mentioning jest.


Solution

  • UPDATE:

    Could you try updating the constructor of the below file with forwardRef, this will get rid of the error.

    mintplayer-ng-bootstrap\libs\mintplayer-ng-bootstrap\navbar\src\navbar-item\navbar-item.component.ts

    export class BsNavbarItemComponent implements AfterContentChecked {
    
      constructor(
        private navbar: BsNavbarComponent,
        element: ElementRef,
        private destroy: DestroyRef,
        @Inject(PLATFORM_ID) private platformId: Object,
        @Optional() 
        @Inject(forwardRef(() => BsNavbarDropdownComponent))  // <- changed here!
              parentDropdown: BsNavbarDropdownComponent,
      ) {
        this.element = element;
        this.parentDropdown = parentDropdown;
    
      }
    

    Github Repo


    nx run video-player-demo:test --testFile=apps/video-player-demo/src/app/app.component.spec.ts