茉莉(Jasmine)编译/创建与beforeall/each怪异作用的组件



我正在为我的应用程序编写一些单元测试,我遇到了一个很奇怪的情况。我构建了一个Angular应用程序,并且正在使用Karma& jasmine进行单位/集成测试。

这是交易:我写了这个代码

describe("Body Container component", () => {
    let component: BodyContainerComponent;
    let fixture: ComponentFixture<BodyContainerComponent>;
    beforeEach(async () => {
        getTestBed().configureTestingModule({
            imports: [AppTestingModule]
        });
        await getTestBed().compileComponents();
        fixture = getTestBed().createComponent(BodyContainerComponent);
        component = fixture.componentInstance;
        component.ngOnInit();
        fixture.detectChanges();
    });

效果很好,测试将正确编译和执行(并通过)。他们确实需要一段时间,我猜是因为每次测试模块都会再次配置并编译。

所以一个试图以这种方式更改它:

 beforeAll(async () => {
    getTestBed().resetTestingModule();
    getTestBed().configureTestingModule({
        imports: [AppTestingModule]
    });
    await getTestBed().compileComponents();
});
beforeEach(async () => {
    fixture = getTestBed().createComponent(BodyContainerComponent);
    component = fixture.componentInstance;
    component.ngOnInit();
    fixture.detectChanges();
});

此版本的同一逻辑/API虽然在getTestbed()。createComponent上失败,失败,

 Error: Illegal state: Could not load the summary for directive BodyContainerComponent.
    error properties: Object({ ngSyntaxError: true })
        at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2430:1)
        at CompileMetadataResolver.push../node_modules/@angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getDirectiveSummary (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:18535:1)
        at JitCompiler.push../node_modules/@angular/compiler/fesm5/compiler.js.JitCompiler.getComponentFactory (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:25979:1)
        at CompilerImpl.push../node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js.CompilerImpl.getComponentFactory (http://localhost:9876/node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js?:162:1)
        at TestingCompilerImpl.push../node_modules/@angular/platform-browser-dynamic/fesm5/testing.js.TestingCompilerImpl.getComponentFactory (http://localhost:9876/node_modules/@angular/platform-browser-dynamic/fesm5/testing.js?:110:1)
        at TestBedViewEngine.push../node_modules/@angular/core/fesm5/testing.js.TestBedViewEngine.createComponent (http://localhost:9876/node_modules/@angular/core/fesm5/testing.js?:1905:1)
        at Object.<anonymous> (http://localhost:9876/src/test/integration/app/components/body-container.integration-spec.ts?:21:32)
        at step (http://localhost:9876/node_modules/tslib/tslib.es6.js?:97:1)
        at Object.next (http://localhost:9876/node_modules/tslib/tslib.es6.js?:78:45)
        at http://localhost:9876/node_modules/tslib/tslib.es6.js?:71:1

我尝试了各种迭代和更改以使其正常工作,但是错误仍然存在。经过一些分析,我可以说:1-异步/等待效果很好,仅在Beforeall完成后才称呼2-每个测试都会给出上面的错误,甚至第一个错误(这很奇怪,因为从逻辑上讲,第一个不应该在2个版本之间更改一英寸

我注意到的一件事是,第一个版本测试是随机摄取的,而第二版似乎遵循订单。第二版本的异步并没有更改任何内容,我也尝试调用各种重置/销毁方法,但似乎没有任何贡献。

您知道为什么会发生这种情况吗?如果无法解决问题,那是可以的,毕竟是在查看整个构建过程时的所有次要优化,我更加好奇为什么会发生这种情况。

编辑:在进行附加分析之后,通过查看测试床实例,我注意到"仅"实现的实现

TestBedViewEngine{_instantiated: false, _compiler: TestingCompilerImpl{_compiler: CompilerImpl{_metadataResolver: ..., _delegate: ..., injector: ...}, _directiveResolver: MockDirectiveResolver{_reflector: ..., _directives: ...}, _pipeResolver: MockPipeResolver{_reflector: ..., _pipes: ...}, _moduleResolver: MockNgModuleResolver{_reflector: ..., _ngModules: ...}, _overrider: MetadataOverrider{_references: ...}}, _moduleRef: null, _moduleFactory: NgModuleFactory_{moduleType: function DynamicTestModule() { ... }, _bootstrapComponents: [], _ngModuleDefFactory: function(_l) { ... }}, _compilerOptions: [], _moduleOverrides: [], _componentOverrides: [], _directiveOverrides: [], _pipeOverrides: [], _providers: [], _declarations: [], _imports: [function AppTestingModule() { ... }], _schemas: [], _activeFixtures: [], _testEnvAotSummaries: function () { ... }, _aotSummaries: [], _templateOverrides: [], _isRoot: true, _rootProviderOverrides: [], platform: PlatformRef{_injector: StaticInjector{parent: ..., source: ..., _records: ...}, _modules: [], _destroyListeners: [], _destroyed: false}, ngModule: function BrowserDynamicTestingModule() { ... }}

beforeall具有:

TestBedViewEngine{_instantiated: false, _compiler: null, _moduleRef: null, _moduleFactory: null, _compilerOptions: [], _moduleOverrides: [], _componentOverrides: [], _directiveOverrides: [], _pipeOverrides: [], _providers: [], _declarations: [], _imports: [], _schemas: [], _activeFixtures: [], _testEnvAotSummaries: function () { ... }, _aotSummaries: [], _templateOverrides: [], _isRoot: true, _rootProviderOverrides: [], platform: PlatformRef{_injector: StaticInjector{parent: ..., source: ..., _records: ...}, _modules: [], _destroyListeners: [], _destroyed: false}, ngModule: function BrowserDynamicTestingModule() { ... }}

我可以通过此输出看到的很大的区别是_compiler,分别为null和实例化。此测试床"快照"是在createComponent调用之前拍摄的

我实际上可以在这里找到问题https://github.com/angular/angular/angular/issues/12409

基本上,总而言之,Angular实际上在功能之前重新定义,并添加了一些非常有用的行为。具体来说,它在这里写:https://github.com/angular/angular/blob/master/packages/core/core/testing/src/before_each.ts.ts#l24

因此,在beforeall中配置的测试模块实际上是在the each中重置的(在createComponent呼叫之前)。而是仅使用the之前实际工作,因为重置调用后配置了模块。

因此,您要么按预期使用之前使用的牺牲速度(Angular的意见是提供每个测试时的服务是新鲜的,这对于无状态物品没有意义),或者您可以选择2种不同的解决方案:1)再次重新定义全局,将其重新定位为默认情况,然后恢复角度的行为:这当然是一个黑客攻击,并且非常不稳定,并且会引发随机错误,因为Angular假设模块是新鲜的,适合其自己的内部设备。2)根本不要使用之前使用之前,请在beforeall中配置模块,而不是要求所有之前的活动以您在每个IT语句上调用的自定义函数

最新更新