简体   繁体   English

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

[英]Angular2 RC5 how to properly configure test module

I'm updating my unit tests for Angular2 RC5.我正在更新 Angular2 RC5 的单元测试。 The changelog notes the following breaking change:变更日志记录了以下重大变更:

addProviders [is deprecated], use TestBed.configureTestingModule instead addProviders [已弃用],请改用TestBed.configureTestingModule

But this seems to take error only when attempting to include a service in a test.但这似乎只有在尝试在测试中包含服务时才会出错。 Where my unit test used to do the following:我的单元测试用于执行以下操作:

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

it should now configure the test module:现在应该配置测试模块:

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

But that now throws an error但这现在会引发错误

Service: MyService encountered a declaration exception FAILED服务:MyService 遇到声明异常 FAILED

Error: Cannot configure the test module when the test module has already been instantiated.错误:当测试模块已经实例化时,无法配置测试模块。 Make sure you are not using inject before TestBed.configureTestingModule .确保您没有在TestBed.configureTestingModule之前使用inject

I have checked that inject isn't been called before the configureTestingModule .我已经检查过在configureTestingModule之前没有调用inject This doesn't affect any other component/directive tests, they seem to pass just fine.这不会影响任何其他组件/指令测试,它们似乎通过得很好。 How can I resolve this error for unit testing a service with RC5?如何解决此错误以使用 RC5 对服务进行单元测试? I realize that I may have to wait until the the testing documentation are updated for RC5 but any insight into possible solutions would be much appreciated.我意识到我可能必须等到 RC5 的测试文档更新,但对可能的解决方案的任何见解都将不胜感激。

From what I have read, you only need to init the test environment once.根据我的阅读,您只需要初始化测试环境一次。 You can then reset the testing module and configure the testing module before each test:然后,您可以在每次测试之前重置测试模块并配置测试模块:

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

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

The upfront configuration is:前期配置是:

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);
}

After reading through the code it seems configureTestingModule will call resetTestingModule internally but I like to declare it in after each for readability purposes.通读代码后,似乎 configureTestingModule 将在内部调用 resetTestingModule 但我喜欢在每个之后声明它以提高可读性。

I had a similar issue and fixed it by resetting the test environment:我有一个类似的问题,并通过重置测试环境修复它:

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);
  }));
});

I am quite the noob when it comes to Angular 2 so I welcome corrections from more knowledgeable folks.谈到 Angular 2,我是个菜鸟,所以我欢迎更多知识渊博的人进行更正。 It seems that one should not have to reset and reinitialize the test environment in every test.似乎不必在每次测试中都必须重置和重新初始化测试环境。 Unfortunately, it was the only way I was able to get it working.不幸的是,这是我能够让它工作的唯一方法。

Stick TestBed.configureTestingModule inside beforeEach like so:TestBed.configureTestingModule放在 beforeEach 中,如下所示:

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

The problem arise when the TestBed is initialized outside a before each when having two spec files or more.当 TestBed 有两个或更多规格文件时,在每个之前在 a 之外初始化时会出现问题。

For example:例如:

  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();
  });
 });

will instanciate a TestBed beforeEach tests, not only the spec file.将在TestBed测试之前实例化一个TestBed ,而不仅仅是规范文件。 Hence, if you have another .spec with a TestBed and a beforeEach it will be interpreted as 2 TestBed instanciated like this:因此,如果您有另一个带有 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();
  });
 });

The error错误

Failed: Cannot configure the test module when the test module has already been instantiated.失败:当测试模块已经实例化时,无法配置测试模块。

will be right, since you instanciate two TestBed (but in two spec files).会是对的,因为您实例化了两个 TestBed(但在两个规范文件中)。

To solve this problem, you must always put the TestBed definition (so the beforeEach ) in a describe like this:为了解决这个问题,你必须总是把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();
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM