Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

In Angular 2.0.0, I am unit testing a component that uses Router. However I get the 'Supplied parameters do not match any signature of call target.' error. In Visual studio code in spec.ts it is the new Router() that is highlighted in red

I really appreciate if someone could let me know what the correct syntax would be? Thanks in advance. My code as follows:

spec.ts

import { TestBed, async } from '@angular/core/testing'; import { NavToolComponent } from './nav-tool.component'; import { ComponentComm } from '../../shared/component-comm.service'; import { Router } from '@angular/router';  describe('Component: NavTool', () => {     it('should create an instance', () => {     let component = new NavToolComponent( new ComponentComm(), new Router());     expect(component).toBeTruthy();     }); }); 

Component constructor

constructor(private componentComm: ComponentComm, private router: Router) {} 
like image 500
Ka Tech Avatar asked Sep 30 '16 12:09

Ka Tech


People also ask

How do I test a router navigate in Angular 12?

We can test routing in Angular by using RouterTestingModule instead of RouterModule to provide our routes. This uses a spy implementation of Location which doesn't trigger a request for a new URL but does let us know the target URL which we can use in our test specs.

How do I test my router navigate in Angular jest?

router = TestBed. get(Router); Then, in the testcase, it('should show news intially ', () => { const navigateSpy = spyOn(router,'navigate'); component.

What is RouterTestingModule?

The modules sets up the router to be used for testing. It provides spy implementations of Location and LocationStrategy .

What unit testing does Angular use?

Jasmine and Karma frameworks are used for Unit Testing of the Angular applications.


2 Answers

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); // TestBed.inject(Router) for Angular 9+      });      it('should navigate', () => {         const component = fixture.componentInstance;         const navigateSpy = spyOn(router, 'navigate');          component.goSomewhere();         expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);     }); }); 
like image 90
Lenny Avatar answered Oct 04 '22 00:10

Lenny


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:

  • Angular docs on Testing for more examples using the Angular testing infrastructure.
like image 38
Paul Samsotha Avatar answered Oct 03 '22 22:10

Paul Samsotha