【问题标题】:How can I unit test components that depend on the RC3 router?如何对依赖于 RC3 路由器的组件进行单元测试?
【发布时间】: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 并开始工作了吗?

【问题讨论】:

标签: typescript angular jasmine


【解决方案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 功能的组件,是吗?我不想测试路由器,我想测试使用路由器的组件。请参阅第二段(现在为粗体)。这在之前使用SpyLocationMockLocationStrategy 是可能的,但MockLocationStrategy 不会在rc4 中导出。
  • 所以你想测试当一个链接被点击时它会导航到正确的页面吗?如果是这样,您可以使用 SpyLocation 的isCurrentPathEqualTo(path: string, query: string = ''): boolean 方法。用JS模拟一个链接点击,然后用这个方法使用expect。我相信你认为这行不通是正确的。在工作中,我们在路由器周围有一个包装器,用于存储我们导航到的路由,因此我们测试该路由日志。
  • 你如何用ActivatedRoute模拟路由参数?
猜你喜欢
  • 2016-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 2014-04-29
相关资源
最近更新 更多