Angular testing: Cannot read property 'nativeElement' of null

Mellville picture Mellville · Oct 15, 2019 · Viewed 14.4k times · Source

I am new in Angular testing and at the moment I am trying to test this piece of code but I'm getting an error concerning the event raised on the DOM:

<li class="list-group-item" *ngFor="let user of users">
  <a class="test-link"[routerLink]="['/detail', user.id]">
    {{user.userName}}
  </a>
</li>

The Test file:

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [AdminComponent, UserDetailComponent],
    imports: [HttpClientModule,RouterTestingModule.withRoutes([
      {path:'detail/:id',
        component: UserDetailComponent}],
    )],
    providers: [UserService, AuthService]
  })
    .compileComponents();
}));

beforeEach(() => {
  router = TestBed.get(Router);
  location = TestBed.get(Location);

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

});

it('test demands redirection', fakeAsync(() => {

  debugElement
    .query(By.css('.test-link'))
    .nativeElement.click();

  tick();

  expect(location.path()).toBe('/detail/testing/1');

}));

Why is click event on the native element is null?

Answer

Archit Garg picture Archit Garg · Oct 15, 2019

This is because when this test will run, your users array will be empty, and hence there will be no element in html with .test-link selector.

Before clicking the element, you should fill the users array and let angular run the change detection so that your anchor tag is available when you click on it.

Code:

it('test demands redirection', fakeAsync(() => {

  component.users = [
    // fill it with user objects
  ];

  fixture.detectChanges();

  debugElement
    .query(By.css('.test-link'))
    .nativeElement.click();

  tick();

  expect(location.path()).toBe('/detail/testing/1');

}));