使用beforeAll而不是beforeEach时,Angular 2 CLI Jasmine单元测试失败

His*_*dow 3 unit-testing jasmine angular-cli angular2-testing angular

我创建了NG-CLI(beta.15)一个新的项目并修改了app.component.spec改变beforeEach,以一个beforeAll和它造成的测试失败,出现以下错误:

失败:无法创建组件AppComponent,因为它未导入测试模块!

我不明白这个错误意味着什么,当然为什么我会在第一时间得到它.

这是修改后的规范:

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

describe('App: Ng2CliTest2', () => {
  beforeAll(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    });
  });

  it('should create the app', async(() => {
    let fixture = TestBed.createComponent(AppComponent);
    let app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));

  it(`should have as title 'app works!'`, async(() => {
    let fixture = TestBed.createComponent(AppComponent);
    let app = fixture.debugElement.componentInstance;
    expect(app.title).toEqual('app works!');
  }));

  it('should render title in a h1 tag', async(() => {
    let fixture = TestBed.createComponent(AppComponent);
    fixture.detectChanges();
    let compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('app works!');
  }));
});
Run Code Online (Sandbox Code Playgroud)

然后我将规范修改为此,前两个测试通过,第三个测试失败并显示以下消息:

失败:尝试使用已销毁的视图:detectChanges

import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';

let fixture;
let app;

describe('App: Ng2CliTest2', () => {
  beforeAll(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent
      ],
    });
    fixture = TestBed.createComponent(AppComponent);
    app = fixture.debugElement.componentInstance;        
  });

  it('should create the app', async(() => {
    expect(app).toBeTruthy();
  }));

  it(`should have as title 'app works!'`, async(() => {
    expect(app.title).toEqual('app works!');
  }));

  it('should render title in a h1 tag', async(() => {
    fixture.detectChanges();
    let compiled = fixture.debugElement.nativeElement;
    expect(compiled.querySelector('h1').textContent).toContain('app works!');
  }));
});
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会有任何失败.

Pau*_*tha 6

在不知情的情况下,Angular实际上将测试模块重置在它自己的卧底中beforeEach(参见testing.ts参考资料)

var _global = <any>(typeof window === 'undefined' ? global : window);

// Reset the test providers and the fake async zone before each test.
if (_global.beforeEach) {
  _global.beforeEach(() => {
    TestBed.resetTestingModule();
    resetFakeAsyncZone();
  });
}
Run Code Online (Sandbox Code Playgroud)

我甚至没有试过这个,但是你想知道它是如何工作的(也许)尝试并且(安全地)禁用这个功能,这是我已经想到的:

在配置中的某个位置已导入

@angular/core/bundles/core-testing.umd.js
Run Code Online (Sandbox Code Playgroud)

这在karma-test-shim.js文件中很多次.该文件包含我们在Angular测试中使用的几乎所有测试实用程序.它几乎是从测试模块导出的所有内容的汇编.这包括添加全局beforeEach调用的上述测试文件.

如果从上述信息中看不出来,您beforeAll的第一次测试只有好处,那么Angular会重置测试台.因此,您正在尝试从空的测试台配置创建组件的下一个测试.