如何将angular2服务注入单元测试? (RC3)

时间:2016-06-28 15:38:38

标签: angular angular2-routing angular2-testing angular2-di

我正在使用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'用   可注射的。

我该如何运作?

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

感谢。

1 个答案:

答案 0 :(得分: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本身进行单元测试,那么创建模拟服务就会失败。如果尝试从该服务调用方法,则可能必须向mock类添加方法或变量。