1
votes

Upgraded angular/primeng packages from 6->7 and now some unit tests are failing. I keep getting a "cannot read property 'root' of undefined" when I try to provide my own mock router for the test bed.

I noticed the Testbed was importing RouterTestingModule as well as providing a mock so I removed the import and still see the issue. Downgrading with the same package-lock fixes the issue, however I need the upgrade and am unsure on how to test the ngOnInit without being able to set the router url/events in a mock..

I'm trying to test the following:

 ngOnInit() {
    this.router.events
      .pipe(takeUntil(this.onDestroy))
      .pipe(filter(e => e instanceof NavigationEnd))
      .subscribe((event) => {
        this.title.setTitle(this.generateTabTitle(this.router.url));
    });

The original test file:

let mockRouterService = {
    url: 'test/testSite',
    events: new Observable(observer => {
      observer.next(new NavigationEnd(0, 'http://mocksite.com/test',
        'http://mocksite.com/test'));
      observer.complete();
    })
  };

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        AppModule,
        RouterTestingModule
      ],
      providers: [
        { provide: APP_BASE_HREF, useValue: '/' },
        { provide: Router, useValue: mockRouterService},
        { provide: Title, useClass: Title},
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.debugElement.componentInstance;
    fixture.detectChanges();

    mockRouterService = TestBed.get(Router);
    mockTitleService = TestBed.get(Title);
  }));

it('should set the title from the first router event', async(() => {
    expect(mockRouterService.events).toBeTruthy();
    expect(mockTitleService.getTitle()).toBe(`Test - Title);
  }));

I can't spyOnProperty for the testbed.router since it is readonly.. Is there any other way to test the ngOnInit since I cannot provide a mock router with event/url set beforehand?

EDIT for the fix: Added routerState: {} to my mockRouterService and the testbed now accepts this the router prvoider again.

1

1 Answers

1
votes

In your case, it's better to use RouterTestingModule instead of a router mock. The root of the problem is that your mock lacks some functionality that is used by the component. This SO answer contains a good example of the RouterTestingModule usage.