Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular unit test how to test a routerLink

How to test a routerLink ?

I tried with

beforeEach(() => {
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    debugEl = fixture.debugElement;
    element = debugEl.nativeElement;
    fixture.detectChanges();
  });
  it('should have href with /login', () => {
    fixture.detectChanges();
    const href = debugEl.query(By.css('a')).nativeElement.getAttribute('href');
    console.error(href) // give me null 
    //expect(expect(href)).toEqual('/login');
  });

But the href var is null. I also tried with .nativeElement.href and give me a void string

like image 522
Whisher Avatar asked Dec 08 '22 16:12

Whisher


1 Answers

In order for routerLink directive to be compiled, router module (more specifically, its test variety, because real routing shouldn't occur in tests) should be imported to test bed:

import { RouterTestingModule } from '@angular/router/testing';

...

TestBed.configureTestingModule({
  imports: [RouterTestingModule]
});

Considering that there is <a routerLink="/login"></a> in component template, this should be true:

const href = debugEl.query(By.css('a')).nativeElement.getAttribute('href');
expect(expect(href)).toEqual('/login');

Considering that routerLink accepts complex configurations, href assertion may be not enough. Even though it relies on RouterTestingModule that should be trusted, it's black box test.

A more specific way is to test routerLink input itself. Considering that there is <a [routerLink]="['/login']"></a> in component template and RouterTestingModule was imported as well, this should be true:

import { RouterLinkWithHref } from '@angular/router';

...

const linkDebugEl = debugEl.query(By.css('a'));
const routerLinkInstance = linkDebugEl.injector.get(RouterLinkWithHref);
expect(routerLinkInstance['commands']).toEqual(['/login']);
expect(routerLinkInstance['href']).toEqual('/login');

This doesn't require RouterTestingModule; RouterLink directive can be replaced with appropriate dummy directive if necessary to test commands input.

like image 123
Estus Flask Avatar answered Dec 10 '22 11:12

Estus Flask