テストのために、 を使用してテスト モジュールを作成しますTestBed
。を使用してTestBed#configureTestingModule
、に渡すのと同じ方法でメタデータ オブジェクトを渡すことができます。@NgModule
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ /* modules to import */ ],
providers: [ /* add providers */ ],
declarations: [ /* components, directives, and pipes */ ]
});
});
ルーティングには、通常の を使用する代わりにRouterModule
、 を使用しますRouterTestingModule
。Router
これによりandが設定されるLocation
ため、自分で設定する必要はありません。呼び出して、ルートを渡すこともできますRouterTestingModule.withRoutes(Routes)
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes([
{ path: 'home', component: DummyComponent }
])
]
})
Location
テストでandを取得するにRouter
は、例のように同じことが機能します。
let router, location;
beforeEach(() => {
TestBed...
});
beforeEach(inject([Router, Location], (_router: Router, _location: Location) => {
router = _router;
location = _location;
}));
必要に応じて各テストに注入することもできます
it('should go home',
async(inject([Router, Location], (router: Router, location: Location) => {
})));
上記は、明示的に呼び出す必要がないことを除いて、async
同様に使用されます。すべての非同期タスクが完了すると、Angular が実際にそれを行います。done
done
プロバイダーを取得する別の方法は、テスト ベッドからです。
let location, router;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([
{ path: 'home', component: DummyComponent }
])],
});
let injector = getTestBed();
location = injector.get(Location);
router = injector.get(Router);
});
ここに完全なテストがあり、例をリファクタリングしています
import { Component } from '@angular/core';
import { Location } from '@angular/common';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { fakeAsync, async, inject, TestBed, getTestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
@Component({
template: `
<router-outlet></router-outlet>
`
})
class RoutingComponent { }
@Component({
template: ''
})
class DummyComponent { }
describe('component: RoutingComponent', () => {
let location, router;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([
{ path: 'home', component: DummyComponent }
])],
declarations: [RoutingComponent, DummyComponent]
});
});
beforeEach(inject([Router, Location], (_router: Router, _location: Location) => {
location = _location;
router = _router;
}));
it('should go home', async(() => {
let fixture = TestBed.createComponent(RoutingComponent);
fixture.detectChanges();
router.navigate(['/home']).then(() => {
expect(location.path()).toBe('/home');
console.log('after expect');
});
}));
});
アップデート
また、単純にルーターをモックしたい場合は、実際には単体テストを行うためのより良い方法である可能性があり、単純に行うことができます
let routerStub;
beforeEach(() => {
routerStub = {
navigate: jasmine.createSpy('navigate'),
};
TestBed.configureTestingModule({
providers: [ { provide: Router, useValue: routerStub } ],
});
});
テストでは、コンポーネントがスタブと対話するときに、スタブが正しい引数で呼び出されることをテストするだけです
expect(routerStub.navigate).toHaveBeenCalledWith(['/route']);
実際にルーティングをテストしたい場合を除き、これがおそらく推奨される方法です。ルーティングを設定する必要はありません。単体テストでは、実際のルーティングを使用している場合、実際にテストしようとしているもの、つまりコンポーネントの動作に影響を与える可能性のある不要な副作用が発生します。コンポーネントの動作は、単にnavigate
メソッドを呼び出すことです。ルーターが機能することをテストする必要はありません。Angular はすでにそれを保証しています。