Angular 2 - 在构造函数中使用Router和routeParams测试组件

时间:2016-02-18 19:13:46

标签: angular angular2-routing

当尝试在构造函数中使用routeParams或路由器测试组件时,会收到错误:

没有RouteParams提供商

这是我的组件示例:     @零件({       选择器:'记忆',       模板:'',
    })     export class TestedComponent {       构造函数(         private _someService:SomeService,         private _routeParams:RouteParams,         private _router:路由器       ){         this.whatever = this._someService.find(this._routeParams.get(' id'));       }

我花了很多时间才找到这个解决方案,我想分享一下!

1 个答案:

答案 0 :(得分:1)

所以我们需要模拟路由器。 我创建了一个名为mockRouter.ts的单独文件:

import {provide} from 'angular2/core';
import {
  Location,
  LocationStrategy,
  ComponentInstruction,
  Router,
  RouteParams
} from 'angular2/router';
import {ResolvedInstruction} from 'angular2/src/router/instruction';
import {SpyObject} from 'angular2/testing_internal';

export class MockRouteParams extends SpyObject {
  private ROUTE_PARAMS = {};

  constructor() { super(RouteParams); }

  set(key: string, value: string) {
    this.ROUTE_PARAMS[key] = value;
  }

  get(key: string) {
    return this.ROUTE_PARAMS[key];
  }
}

export class MockRouter extends SpyObject {
  constructor() { super(Router); }
  isRouteActive(s) { return true; }
  generate(s) {
    return new ResolvedInstruction(new ComponentInstruction('detail', [], null, null, true, '0'), null, {});
  }
}
export class MockLocationStrategy extends SpyObject {
  constructor() { super(LocationStrategy); }
}
export class MockLocation extends SpyObject {
  constructor() { super(Location); }
}

export class MockRouterProvider {
  mockRouter: MockRouter = new MockRouter();
  mockRouteParams: MockRouteParams = new MockRouteParams();
  mockLocationStrategy: MockLocationStrategy = new MockLocationStrategy();
  mockLocation: MockLocation = new MockLocation();

  setRouteParam(key: string, value: any) {
    this.mockRouteParams.set(key, value);
  }

  getProviders(): Array<any> {
    return [
      provide(Router, {useValue: this.mockRouter}),
      provide(RouteParams, {useValue: this.mockRouteParams}),
      provide(Location, {useValue: this.mockLocation}),
      provide(LocationStrategy, {useValue: this.mockLocationStrategy})
    ];
  }
}

然后在我的测试中我做了:

import{MockRouterProvider} from '../services/specs/mockRouter';
describe('Tested component', () => {
  let mockRouterProvider = new MockRouterProvider();
  beforeEachProviders(() => [
    TestedComponent,
    ...all others,

    HTTP_PROVIDERS,
    mockRouterProvider.getProviders(),

  ]);

  let tcb: TestComponentBuilder;

  beforeEach(
    inject(
      [TestComponentBuilder, FakerService], (...injectables) => {
        [tcb] = injectables;
      }
    )
  );
  it('should render',
    injectAsync([], () => {

      mockRouterProvider.setRouteParam('id', '1');
      return tcb.createAsync(MemoryComponent)
        .then((componentFixture) => {
          componentFixture.detectChanges();
          let compiled = componentFixture.nativeElement;

          expect(compiled.firstChild).toHaveCssClass('tested-wrapper');

          componentFixture.destroy();
        }).catch((e) => {
          expect(true).toBeFalsy(`Error: ${e.message}`);
        });
    })
  );

希望这会有所帮助!