Angular2 RC5如何正确配置测试模块

时间:2016-08-16 21:59:52

标签: unit-testing angular

我正在更新Angular2 RC5的单元测试。 changelog注意到以下重大变化:

  

addProviders [已弃用],请改用<{1}}

但是,只有在尝试在测试中包含服务时,这似乎才会出错。我的单元测试用于执行以下操作:

TestBed.configureTestingModule

现在应该配置测试模块:

beforeEach(() => addProviders([
    MyService,
    MockBackend,
    ... 
]));

但现在抛出错误

  

服务:MyService遇到声明异常FAILED

     

错误:当测试模块已经实例化时,无法配置测试模块。确保在TestBed.configureTestingModule({ providers: [ StoryService, MockBackend, ... ] }); 之前未使用inject

我已检查TestBed.configureTestingModule之前未调用inject。这不会影响任何其他组件/指令测试,它们似乎传递得很好。如何使用RC5对服务进行单元测试来解决此错误?我意识到我可能要等到RC5的测试文档更新,但是对于可能的解决方案的任何见解将非常感激。

4 个答案:

答案 0 :(得分:6)

根据我的阅读,您只需要初始化测试环境一次。然后,您可以在每次测试之前重置测试模块并配置测试模块:

beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ GridComponent ]
        });
    });

    afterEach(() => {
        TestBed.resetTestingModule();
    });

前期配置为:

var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');

try {
    testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
} catch ($error) {
    console.log("test env failure" + $error);
}

在阅读完代码之后,看起来configureTestingModule会在内部调用resetTestingModule,但为了便于阅读,我想在每个之后声明它。

答案 1 :(得分:4)

TestBed.configureTestingModule贴在之前,如下所示:

beforeEach(() => {
    TestBed.configureTestingModule({
        providers: [
            StoryService,
            MockBackend,
            ...
]
    });
});

答案 2 :(得分:4)

我有一个类似的问题并通过重置测试环境来修复它:

import {MyService} from './my.service';
import {inject, TestBed} from '@angular/core/testing/test_bed';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } 
       from '@angular/platform-browser-dynamic/testing';

describe('MyService', () => {
  beforeEach(() => {
    // Must reset the test environment before initializing it.
    TestBed.resetTestEnvironment();

    TestBed
      .initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting())
      .configureTestingModule({
        providers: [
          MyService
        ]
    });
  });

  it('should do something', inject([MyService], (s: MyService) => {
    let r = s.getResult();
    expect(r.length).toBe(2);
  }));
});

对于Angular 2来说,我是一个非常棒的人,所以我欢迎更多知识渊博的人进行更正。似乎不应该在每次测试中重置和重新初始化测试环境。不幸的是,这是我能够让它发挥作用的唯一方式。

答案 3 :(得分:1)

当具有两个或更多规范文件的TestBed在a之前的外部初始化时,会出现问题。

例如:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
describe('AppComponent', () => {
  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
 });

将在每次测试之前实例化一个TestBed,而不仅仅是规格文件。因此,如果您还有一个带有TestBed和beforeEach的.spec,它将被解释为2个TestBed,如下所示:

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
describe('AppComponent', () => {
  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
 });

错误

失败:测试模块具有以下功能时,无法配置测试模块 已经实例化。

将是正确的,因为您实例化了两个TestBed(但在两个规格文件中)。

要解决此问题,必须始终将TestBed定义(因此beforeEach)放在这样的描述中:

describe('AppComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  it('should create the app', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app).toBeTruthy();
  });
});
相关问题