Angular 2/4/6/7 - Unit Testing with Router Angular 2/4/6/7 - Unit Testing with Router angular angular

Angular 2/4/6/7 - Unit Testing with Router


You can also just use the RouterTestingModule and just spyOn the navigate function like this...

import { TestBed } from '@angular/core/testing';import { RouterTestingModule } from '@angular/router/testing';import { Router } from '@angular/router';import { MyModule } from './my-module';import { MyComponent } from './my-component';describe('something', () => {    let fixture: ComponentFixture<LandingComponent>;    let router: Router;    beforeEach(() => {        TestBed.configureTestingModule({            imports: [                MyModule,                RouterTestingModule.withRoutes([]),            ],        }).compileComponents();        fixture = TestBed.createComponent(MyComponent);        router = TestBed.get(Router);    });    it('should navigate', () => {        const component = fixture.componentInstance;        const navigateSpy = spyOn(router, 'navigate');        component.goSomewhere();        expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);    });});


It's because the Route has some dependencies it expects passed to its constructor.

If you're using Angular components, you shouldn't be trying to do isolated tests. You should use the Angular testing infrastructure to prepare the test environment. This means letting Angular create the component, letting it inject all the required dependencies, instead of you trying to create everything.

To get you started, you should have something like

import { TestBed } from '@angular/core/testing';describe('Component: NavTool', () => {  let mockRouter = {    navigate: jasmine.createSpy('navigate')  };  beforeEach(() => {    TestBed.configureTestingModule({      declarations: [ NavToolComponent ],      providers: [        { provide: Router, useValue: mockRouter },        ComponentComm      ]    });  });  it('should click link', () => {    let fixture = TestBed.createComponent(NavToolComponent);    fixture.detectChanges();    let component: NavToolComponent = fixture.componentInstance;    component.clickLink('home');    expect(mockRouter.navigate).toHaveBeenCalledWith(['/home']);  });});

Or something like that. You use the TestBed to configure a module from scratch for the testing. You configure it pretty much the same way with an @NgModule.

Here we are just mocking the router. Since we are just unit testing, we may not want the real routing facility. We just want to make sure that it is called with the right arguments. The mock and spy will be able to capture that call for us.

If you do want to use the real router, then you need to use the RouterTestingModule, where you can configure routes. See an example here and here

See Also:


Jasmine goes one better with full spy objects...

describe('Test using router', () => {    const router = jasmine.createSpyObj('Router', ['navigate']);    ...    beforeEach(async(() => {        TestBed.configureTestingModule({            providers: [  { provide: Router, useValue: router } ],            ...    });        });