如何对依赖于 RC3 路由器的组件进行单元测试?
Posted
技术标签:
【中文标题】如何对依赖于 RC3 路由器的组件进行单元测试?【英文标题】:How can I unit test components that depend on the RC3 router? 【发布时间】:2016-11-03 14:46:45 【问题描述】:我正在尝试获取与 RC1 一起使用“新新”路由器的单元测试。我怎样才能在3.0.0-alpha.8
上实现这一点?
我的依赖:
"@angular/common": "2.0.0-rc.3",
"@angular/compiler": "2.0.0-rc.3",
"@angular/core": "2.0.0-rc.3",
"@angular/forms": "0.2.0",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
"@angular/router": "3.0.0-beta.2",
我要测试的组件使用routerLink
指令:
import ROUTER_DIRECTIVES from '@angular/router';
@Component(
selector: 'app-topmenu',
template: require('./app-topmenu.tpl.html'),
directives: [ROUTER_DIRECTIVES]
)
export class TopMenu
<nav class="app-top-menu">
<a *ngFor="let link of links" [routerLink]="link.route">link.text</a>
</nav>
以前,使用 rc1,我使用类似这样的东西来对我的组件进行单元测试:
import Location from '@angular/common';
import SpyLocation from '@angular/common/testing';
import Router, RouteRegistry, ROUTER_DIRECTIVES, ROUTER_PRIMARY_COMPONENT from '@angular/router-deprecated';
import RootRouter from '@angular/router-deprecated/src/router';
describe('Router link capabilities', () =>
beforeEachProviders(() => [
RouteRegistry,
provide: Location, useClass: SpyLocation ,
provide: ROUTER_PRIMARY_COMPONENT, useValue: TestComponent ,
provide: Router, useClass: RootRouter
]);
it('creates routerLinks with the expected URLs', fakeAsync(
inject([TestComponentBuilder, Location], (tcb: TestComponentBuilder, spyLocation: SpyLocation) =>
tcb.overrideTemplate(TestComponent, `
<app-top-menu [links]='[
text: "A", route: ["/TestA/TestB/TestC"] ,
text: "B", route: ["/TestA", "TestB", "TestC"]
]'></app-top-menu>
<router-outlet></router-outlet>
`).createAsync(TestComponent)
.then((fixture: ComponentFixture<TestComponent>) =>
fixture.detectChanges();
spyLocation.simulateUrlPop('url-a/url-b/url-c');
tick();
fixture.detectChanges();
let nativeLinks: HTMLAnchorElement[] = fixture.nativeElement.querySelectorAll('a');
expect(nativeLinks.length).toBe(2);
expect(nativeLinks[0].textContent).toBe('A');
expect(nativeLinks[1].textContent).toBe('B');
);
)
));
);
当我尝试将 routerLink
导入从 @angular/router-deprecated
切换到从 @angular/router
导入 ROUTER_DIRECTIVES
时,我收到一个错误:
ORIGINAL EXCEPTION: Platforms have to be created via `createPlatform`!
我可以在网上找到有关测试“新新”路由器的所有文档,createPlatform 消息指的是提供 ROUTER_FAKE_PROVIDERS
,它似乎包含在 rc2 中,但随 rc3 一起消失了:
import ROUTER_FAKE_PROVIDERS from '@angular/router/testing';
// ^ [ts] Cannot find module '@angular/router/testing'.
在node_modules/@angular/router
文件夹中搜索编译的.d.ts
文件,我也没有找到任何关于testing/mocks/fakes的引用。
有人迁移到 rc3 并开始工作了吗?
【问题讨论】:
看看这些测试github.com/angular/angular/blob/master/modules/%40angular/… 【参考方案1】:要测试 RC3 (3.0.0-alpha.*) 路由器,您需要做一些与以前版本中路由器设置不同的事情。
您需要像这样定义RouterConfig
:
import provideRouter, RouterConfig from '@angular/router';
export const APP_ROUTES : RouterConfig = [
path: '', component: AppComponent,
// more paths
];
export const APP_ROUTE_PROVIDERS = [
provideRouter(APP_ROUTES)
];
然后在你的测试文件中
import ActivatedRoute, RouterConfig, Router from '@angular/router';
class MockRouter createUrlTree()
class MockActivatedRoute
beforeEachProviders(() => [
provide(Router, useClass: MockRouter ),
provide(ActivatedRoute, useClass: MockActivatedRoute ),
]);
describe()
// etc
您的路由器现在可以测试了。
对于 RC4:
import ActivatedRoute, RouterConfig, Router from '@angular/router';
class MockRouter createUrlTree()
class MockActivatedRoute
describe()
beforeEach(() => [
addProviders([
provide(Router, useClass: MockRouter ),
provide(ActivatedRoute, useClass: MockActivatedRoute ),
]);
]);
//etc
【讨论】:
但这并不能让我测试依赖于实际routerLink
功能的组件,是吗?我不想测试路由器,我想测试使用路由器的组件。请参阅第二段(现在为粗体)。这在之前使用SpyLocation
和MockLocationStrategy
是可能的,但MockLocationStrategy
不会在rc4 中导出。
所以你想测试当一个链接被点击时它会导航到正确的页面吗?如果是这样,您可以使用 SpyLocation 的isCurrentPathEqualTo(path: string, query: string = ''): boolean
方法。用JS模拟一个链接点击,然后用这个方法使用expect。我相信你认为这行不通是正确的。在工作中,我们在路由器周围有一个包装器,用于存储我们导航到的路由,因此我们测试该路由日志。
你如何用ActivatedRoute
模拟路由参数?以上是关于如何对依赖于 RC3 路由器的组件进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章