Developer
Developer

Reputation: 4321

Jest Angular test NavigationEnd

Here is my component code that i want to test:

allpages: Array<Page> = [
  { name: 'Home', url: '/home' },
];

constructor(private router: Router) {
    this.$routerEvent = this.router.events.subscribe((event: Event) => {
      if (event instanceof NavigationEnd) {
        let route = event.url !== '/' ? event.url : event.urlAfterRedirects;
        this.currentPage = this.allpages.find(
          (page) => page.url === route
        );
      }
    });
  }

Here is my test:

beforeEach(async () => {
  TestBed.configureTestingModule({
    declarations: [NavigationBarComponent],
    imports: [MatIconModule, RouterTestingModule],
  }).compileComponents();

  fixture = TestBed.createComponent(NavigationBarComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

it('should set home page as current page', inject([Router], (router: Router) => {
  router.initialNavigation();
  expect(component.currentPage).toEqual({ name: 'Home', url: '/home' });
}));

Test fails because component.currentPage = undefined.

I have read that navigation is an async operation, how do i properly should implement the test, or maybe i went absolutely incorrect way?

Upvotes: 1

Views: 937

Answers (1)

Vikas
Vikas

Reputation: 12036

To test router events, we need to mock the router service object. In the test session configuration, we will replace events property of router as an Observable object. To have access to the events observable object, we create a separate variable of ReplaySubject<RouterEvent>.

 const eventSubject = new ReplaySubject<RouterEvent>(1);

Crate a router mock

const routerMock = {
     events: eventSubject.asObservable(),
 };

While using mock object do not use RouterTestingModule
Explanation:Angular 2 Final Release Router Unit Test

beforeEach(async () => {
  TestBed.configureTestingModule({
    declarations: [NavigationBarComponent],
    imports: [MatIconModule],
    providers: [
        {provide: Router, useValue: routerMock} <-- Override with mock object
    ]

  }).compileComponents();

  fixture = TestBed.createComponent(NavigationBarComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

it('should set home page as current page', () => {
   // simulate the navigation end events
    eventSubject.next(new NavigationEnd(1, '/home', '/urlAfterRedirect'));
    expect(app.currentPage).toEqual({ name: 'Home', url: '/home' });
});

Ref:Approach using Jasmine
More

Upvotes: 3

Related Questions