web-dev-qa-db-ja.com

Angular 2/4/6/7-ルーターを使用した単体テスト

Angular 2.0.0では、ルーターを使用するコンポーネントの単体テストを行っています。ただし、「提供されたパラメーターは、呼び出し先の署名と一致しません」というメッセージが表示されます。エラー。 spec.tsのVisual Studioコードでは、赤で強調表示されているのは新しいRouter()です

誰かが正しい構文が何であるかを私に知らせることができたら本当に感謝していますか?前もって感謝します。次のような私のコード:

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

コンポーネントコンストラクタ

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

また、RouterTestingModuleを使用して、次のようにナビゲート関数をspyOnすることもできます。

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

Routeには、コンストラクターに渡されると予想されるいくつかの依存関係があるためです。

Angularコンポーネントを使用している場合、独立したテストを実行するべきではありません。テスト環境を準備するには、Angularテストインフラストラクチャを使用する必要があります。これは、すべてを作成しようとする代わりに、Angularにコンポーネントを作成させ、必要なすべての依存関係をinjectさせることを意味します。

始めるには、次のようなものが必要です

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

またはそのようなもの。 TestBedを使用して、テスト用にゼロからモジュールを構成します。 @NgModuleを使用して、ほぼ同じ方法で構成します。

ここでは、ルーターをock笑しています。単体テストであるため、実際のルーティング機能は必要ない場合があります。正しい引数で呼び出されることを確認したいだけです。モックと spy は、その呼び出しをキャプチャすることができます。

実際のルーターをdo使用する場合は、RouterTestingModuleを使用する必要があります。ここで、ルートを構成できます。例を参照してください here および here

関連項目:

20
Paul Samsotha

ジャスミンは、完全なスパイオブジェクトでより良くなります...

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

コンポーネントコントローラーにルートサービスを注入する場合の例:

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

navigate()などの他の機能をテストすることもできます。念のため:

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

すべてのモックコンポーネント(mock.components.specs.ts)を含む私のファイル

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

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

export class DummyHomeComponent { }