wake-up-neo.com

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

In Angular 2.0.0 teste ich eine Komponente, die Router verwendet. Es wird jedoch die Fehlermeldung "Die angegebenen Parameter stimmen nicht mit der Signatur des Anrufziels überein." .ts ist der neue Router (), der rot markiert ist

Ich würde es wirklich begrüßen, wenn mir jemand mitteilen könnte, wie die korrekte Syntax lauten würde. Danke im Voraus. Mein Code wie folgt:

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();
  });
});

Komponentenkonstruktor

constructor(private componentComm: ComponentComm, private router: Router) {}
47
Ka Tech

Sie können auch einfach das RouterTestingModule verwenden und die Navigationsfunktion wie folgt ausspähen ...

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', () => {
        let component = fixture.componentInstance;
        let navigateSpy = spyOn(router, 'navigate');

        component.goSomewhere();
        expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);
    });
});
90
Lenny

Dies liegt daran, dass das Route einige erwartete Abhängigkeiten aufweist, die an seinen Konstruktor übergeben werden.

Wenn Sie Angular Komponenten verwenden, sollten Sie nicht versuchen, isolierte Tests durchzuführen. Sie sollten die Testinfrastruktur Angular verwenden, um die Testumgebung vorzubereiten. Dies bedeutet, dass Sie Angular die Komponente erstellen lassen, injizieren alle erforderlichen Abhängigkeiten, anstatt zu versuchen, alles zu erstellen.

Damit Sie anfangen können, sollten Sie etwas wie haben

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']);
  });
});

Oder etwas ähnliches. Mit dem TestBed konfigurieren Sie ein Modul für den Test von Grund auf neu. Du konfigurierst es ziemlich genau so mit einem @NgModule.

Hier verspotten wir nur den Router. Da wir nur Unit-Tests durchführen, möchten wir möglicherweise nicht die echte Routing-Funktion. Wir wollen nur sicherstellen, dass es mit den richtigen Argumenten aufgerufen wird. Der Schein- und Spion wird in der Lage sein, diesen Ruf für uns zu erfassen.

Wenn Sie do den realen Router verwenden möchten, müssen Sie den RouterTestingModule verwenden, in dem Sie Routen konfigurieren können. Siehe ein Beispiel hier und hier

Siehe auch:

20
Paul Samsotha

Jasmine macht es besser mit Spionageobjekten ...

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

Hier ein Beispiel, wenn wir Route-Service in unseren Komponenten-Controller einspeisen:

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; // Because we inject service in our component
import { Router } from '@angular/router'; // Just if we need to test Route Service functionality

import { AppComponent } from './app.component';
import { DummyLoginLayoutComponent } from '../../../testing/mock.components.spec'; // Because we inject service in your component

describe('AppComponent', () => {
  let router: Router; // Just if we need to test Route Service functionality

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        DummyLoginLayoutComponent // Because we inject service in our component
      ],
      imports: [
        RouterTestingModule.withRoutes([
          { path: 'login', component: DummyLoginLayoutComponent },
        ]) // Because we inject service in our component
      ],
    }).compileComponents();

    router = TestBed.get(Router); // Just if we need to test Route Service functionality
    router.initialNavigation(); // Just if we need to test Route Service functionality
  }));

  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});

Wir können auch andere Funktionalitäten wie navigate() testen. Nur für den Fall:

it('should call eventPage once with /register path if event is instanceof NavigationStart', fakeAsync(() => {
    spyOn(analyticService, 'eventPage');
    router.navigate(['register'])
      .then(() => {
        const baseUrl = window.location.Origin;
        const url = `${baseUrl}/register`;
        expect(analyticService.eventPage).toHaveBeenCalledTimes(1);
        expect(analyticService.eventPage).toHaveBeenCalledWith(url);
      });
}));

Meine Datei mit allen Scheinkomponenten (mock.components.specs.ts)

import { Component } from '@angular/core';

@Component({
    selector: 'home',
    template: '<div>Dummy home component</div>',
    styleUrls: []
})

export class DummyHomeComponent { }