5

我正在使用RC3. 我正在实施Angular2此处记录的新路由器:https ://angular.io/docs/ts/latest/guide/router.html

一切正常,但我在单元测试中遇到问题。具体来说,我无法将Angular2服务注入到我的单元测试中。

我的相关组件代码是:

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

@Component({
  templateUrl: ...
  styleUrls: ...
})

export class Route1DetailComponent {

  constructor(private route:ActivatedRoute) {
    console.log(route);
  }
}

我的单元测试看起来像:

import {
  expect, it, iit, xit,
  describe, ddescribe, xdescribe,
  beforeEach, beforeEachProviders, withProviders,
  async, inject
} from '@angular/core/testing';

import {ActivatedRoute} from '@angular/router';
import {Route1DetailComponent} from './route1-detail.component';
import {TestComponentBuilder} from '@angular/compiler/testing';

describe('route1-detail.component.ts', () => {

  beforeEachProviders(() => [
    {provide: ActivatedRoute, useClass: ActivatedRoute}
  ]);

  it('should instantiate component',
    async(inject([TestComponentBuilder, ActivatedRoute], (tcb:TestComponentBuilder, ar: ActivatedRoute) => {
      tcb.createAsync(Route1DetailComponent).then((fixture) => {
        expect(fixture.componentInstance instanceof Route1DetailComponent).toBe(true, 'should create Route1DetailComponent');
        console.log(ar);
    });
  })));
});

“应该实例化组件”单元测试失败。错误是:

无法解析“ActivatedRoute”的所有参数(?、?、?、?、?)。确保所有参数都用 Inject 修饰或具有有效的类型注释,并且 'ActivatedRoute' 用 Injectable 修饰。

我如何让这个工作?

当我不注入时,ActivatedRoute一切正常。

谢谢。

4

1 回答 1

9

在进行单元测试时,有时某个服务会因为没有在正常环境中使用而导致问题。您可以测试它是否已被调用,而无需在整个服务中运行单元测试。通过创建一个模拟类来做到这一点。

describe('route1-detail.component.ts', () => {

class MockActivatedRoute {}

beforeEachProviders(() => [
    {provide: ActivatedRoute, useClass: MockActivatedRoute}
  ]);

it('should instantiate component',
  async(inject([TestComponentBuilder, ActivatedRoute], (tcb:TestComponentBuilder, ar: MockActivatedRoute) => {
  tcb.createAsync(Route1DetailComponent).then((fixture) => {
    expect(fixture.componentInstance instanceof Route1DetailComponent).toBe(true, 'should create Route1DetailComponent');
    console.log(ar);
  });
})));

注意这部分:inject([TestComponentBuilder, ActivatedRoute], (tcb:TestComponentBuilder, ar: MockActivatedRoute。当代码在寻找 ActivatedRoute 时,您正在向它传递模拟服务。当然,如果您专门尝试对 ActivatedRoute 本身进行单元测试,那么创建模拟服务会破坏该目的。如果模拟类尝试从该服务调用方法,您可能必须向模拟类添加方法或变量。

于 2016-06-28T16:36:17.407 回答