11

I am new to writing unit test cases for angular. I have to write a test case for ngAfterViewInit. I don't know how to start. I am using angular 7.

My component code:

export class MyAccessComponent implements OnInit, AfterViewInit {

    // Spinner
    pageLoaded: boolean;
    @Input() diameter = 64;
    @Input() strokeWidth = 7;

    // Icons
    faEdit = faEdit;

    dataSource;
    @ViewChild(MatPaginator) paginator: MatPaginator;

    constructor(private router: Router, private userService: UserService) { }

    ngOnInit() {
        this.pageLoaded = false;
        // Data table init
        this.getUsers();
    }

    ngAfterViewInit() {
        setTimeout(() => {
            this.pageLoaded = true;
        }, 500);
    }
}
Teasel
  • 1,330
  • 4
  • 18
  • 25
Ramesh vemula
  • 149
  • 2
  • 2
  • 12

2 Answers2

15

You can invoke lifecycle hooks programmatically using the component instance, like:

beforeEach(() => {
  fixture = TestBed.createComponent(MyAccessComponent);
  component = fixture.componentInstance;
  fixture.detectChanges();
});

it('should set pageLoaded after view init', () => {
  component.ngAfterViewInit();
  expect(component.pageLoaded).toBe(true);
});

Keep in mind that since you are using a timeout in the hook, you'll need to use fakeAsync to test properly

  • it('Should call after view init', fakeAsync((): void => { component.ngAfterViewInit(); let pageLoaded = false; setTimeout(() => { pageLoaded = true; }, 500); expect(component.pageLoaded).toBe(false); })); BUT I am getting error likeError: 2 timer(s) still in the queue. – Ramesh vemula Mar 21 '19 at 10:03
  • How you can use `fakeAsync` to test timeouts is a different question. Here's an example though https://stackoverflow.com/a/54358067/4544288 – Massimiliano Sartoretto Mar 21 '19 at 10:06
  • 1
    I was testing a directive attached to a component. Calling `fixture.detectChanges();` triggered `ngAfterViewInit()` of a directive which is not executed otherwise. Thank you @MassimilianoSartoretto! – dim Nov 10 '19 at 19:41
0

Consider using the new approach to testing:

describe('MyComponent', () => {

  let component: MyComponent;

  beforeEach(() => {
    component = new MyComponent(mockMyService());
  });

  describe('ngAfterViewInit', () => {
    it('should do stuff', () => {
      component.ngAfterViewInit();
      expect(component.something.toEqual('something');
    });
  });

});

This is much cleaner and faster-to-test than having to invoke the TestBed

Boris Yakubchik
  • 3,861
  • 3
  • 34
  • 41