Expected spy navigate to have been called with [ [ '/login' ] ] but it was never called

566 Views Asked by At

I am writing test case for a below block of code:

someFn() {
    if (this.loginStatus === '1') {
      this.router.navigate(['/login']);
    } 
}

In my spec file:

import { Router } from '@angular/router'
describe('MyComponent', () => {
 let routerStub;
 beforeEach(async(() => { 
   routerStub = {
      navigate: jasmine.createSpy('navigate'),
    };
   TestBed.configureTestingModule({
     declarations: [MyComponent],
     providers: [       
        { provide: Router, useValue: routerStub },
      ],
   }).compileComponents()
 });

 beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.autoDetectChanges();
  });

  it('navigate to login', () => {
     component.loginStatus = '1';
     component.someFn();
     expect(routerStub.navigate).toHaveBeenCalledWith(['/login']);
  });
})

The above gives me the error: Expected spy navigate to have been called with [ [ '/login' ] ] but it was never called.

How do I solve this? I have tried a lot of solutions from SO, but nothing seems to work for me.

Code is written in Angular 7 and I am using jasmine+karma.

1

There are 1 best solutions below

0
Manrah On

Try with below way :

import { Router } from '@angular/router'
    describe('MyComponent', () => {
     let router: Router;
     beforeEach(async(() => { 
       TestBed.configureTestingModule({
         declarations: [MyComponent],
         providers: [       
            { provide: Router, useValue: routerStub },
          ],
       }).compileComponents()
     });

     beforeEach(() => {
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;
        router = TestBed.get(Router);
        fixture.detectChanges();
      });

      it('navigate to login', () => {
      const spy = spyOn(router, 'navigate');
         component.loginStatus = '1';
         component.someFn();
         expect(router.navigate).toHaveBeenCalledWith(['/login']);
      });
    })

Another way using routerStub:-

       import { Router } from '@angular/router';
 
       class RouterStub {
          public navigate(params: any[]): void {}
        }
 
        describe('MyComponent', () => {
         let router: Router;
         beforeEach(async(() => { 
           TestBed.configureTestingModule({
             declarations: [MyComponent],
             providers: [       
                { provide: Router, useClass: RouterStub },
              ],
           }).compileComponents()
         });
        
         beforeEach(() => {
            fixture = TestBed.createComponent(MyComponent);
            component = fixture.componentInstance;
            router = TestBed.get(Router);
            fixture.detectChanges();
          });
        
          it('navigate to login', () => {
          const spy = spyOn(router, 'navigate');
             component.loginStatus = '1';
             component.someFn();
             expect(router.navigate).toHaveBeenCalledWith(['/login']);
          });
        })