【问题标题】:Jasmine tests fail on: Component is not part of any NgModule or the module has not been imported into your moduleJasmine 测试失败:组件不是任何 NgModule 的一部分或模块尚未导入您的模块
【发布时间】:2019-09-27 18:29:51
【问题描述】:

在创建新组件后,我几乎在所有测试中都遇到了这个错误:

SampleComponent > should create
Failed: Component TuzGraphComponent is not part of any NgModule or the module has not been imported into your module.
Error: Component TuzGraphComponent is not part of any NgModule or the module has not been imported into your module.
    at JitCompiler._createCompiledHostTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25493:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25469:1
    at <Jasmine>
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25466:1
    at <Jasmine>
    at JitCompiler._compileComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25455:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25393:1
    at Object.then (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2166:27)
    at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25391:1)
    at JitCompiler.compileModuleAndAllComponentsAsync (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25353:1)
Error: Component TuzGraphComponent is not part of any NgModule or the module has not been imported into your module.
Error: Component TuzGraphComponent is not part of any NgModule or the module has not been imported into your module.
    at JitCompiler._createCompiledHostTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25493:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25469:1
    at <Jasmine>
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25466:1
    at <Jasmine>
    at JitCompiler._compileComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25455:1)
    at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25393:1
    at Object.then (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:2166:27)
    at JitCompiler._compileModuleAndAllComponents (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25391:1)
    at JitCompiler.compileModuleAndAllComponentsSync (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/fesm2015/compiler.js:25350:1)
Expected undefined to be truthy.
Error: Expected undefined to be truthy.
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/webpack:/src/app/sandboxviews/sample/sample.component.spec.ts:85:23)
    at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-evergreen.js:359:1)
    at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:308:1)

所以我将TuzGraphComponent 添加到我所有测试的声明中。

首先,必须有比手动添加任何新组件到每个现有测试文件更简单的方法?!?!

无论如何,这修复了大部分测试。仍然有几个文件有相同的错误,但是当我打开文件并比较它们时,故障消失了。我真的不知道发生了什么变化。在其中一个文件中,我只是在 Webstorm 中点击“重新格式化文件”,这似乎可以修复它,在另一个文件中,我将位于其自身行上的 { 移回其上方的行(结果:({)和这似乎解决了它。

但是仍然有一个测试文件失败,同样的错误;这实际上是我在上面发布的错误。

我将把那个文件粘贴到这里,也许其他人能发现其中的区别?

import {async, ComponentFixture, TestBed} from '@angular/core/testing';

import {AccessdeniedComponent} from '../../pages/accessdenied/accessdenied.component';
import {AppMainComponent} from '../../app.main.component';
import {AppSubMenuComponent, LeftmenuComponent} from '../../leftmenu/leftmenu.component';
import {CalibrationComponent} from '../calibration/calibration.component';
import {ControlComponent} from '../control/control.component';
import {DataviewerComponent} from '../dataviewer/dataviewer.component';
import {ExperimentComponent} from '../experiment/experiment.component';
import {FilemanagerComponent} from '../filemanager/filemanager.component';
import {FooterComponent} from '../../footer/footer.component';
import {HeaderbarComponent} from '../../headerbar/headerbar.component';
import {LoginComponent} from '../../pages/login/login.component';
import {MethodComponent} from '../method/method.component';
import {NotfoundComponent} from '../../pages/notfound/notfound.component';
import {TuneComponent} from '../tune/tune.component';
import {AccordionModule} from 'primeng/accordion';
import {AppRoutingModule} from '../../app-routing.module';
import {BlockUIModule} from 'primeng/blockui';
import {CheckboxModule} from 'primeng/checkbox';
import {DialogModule} from 'primeng/dialog';
import {DropdownModule} from 'primeng/dropdown';
import {FormsModule} from '@angular/forms';
import {InputSwitchModule} from 'primeng/inputswitch';
import {InputTextModule} from 'primeng/inputtext';
import {OverlayPanelModule} from 'primeng/overlaypanel';
import {SampleComponent} from './sample.component';
import {ScrollPanelModule, SpinnerModule} from 'primeng/primeng';
import {TableModule} from 'primeng/table';
import {TuzGraphComponent} from '../tuz-graph/tuz-graph.component';

describe('SampleComponent', () => {
  let component: SampleComponent;
  let fixture: ComponentFixture<SampleComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AccessdeniedComponent,
        AppMainComponent,
        AppSubMenuComponent,
        CalibrationComponent,
        ControlComponent,
        DataviewerComponent,
        ExperimentComponent,
        FilemanagerComponent,
        FooterComponent,
        HeaderbarComponent,
        LeftmenuComponent,
        LoginComponent,
        MethodComponent,
        NotfoundComponent,
        SampleComponent,
        TuneComponent,
        TuzGraphComponent
      ],
      imports: [
        AccordionModule,
        AppRoutingModule,
        BlockUIModule,
        CheckboxModule,
        DialogModule,
        DropdownModule,
        FormsModule,
        InputSwitchModule,
        InputTextModule,
        OverlayPanelModule,
        ScrollPanelModule,
        SpinnerModule,
        TableModule
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SampleComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

【问题讨论】:

    标签: angular jasmine karma-runner


    【解决方案1】:

    我也有类似的问题。我不知道问题的根源是什么,但是一个接一个地运行您之前对 sample.component.spec.ts 的所有测试并打开 Web 控制台!确保在每个测试中您的控制台中没有任何错误,然后再次一起运行所有测试!有时你的错误不会在测试中失败但会损坏下一个错误

    【讨论】:

      【解决方案2】:

      您必须在所有测试中提供新组件的原因是您将真正的组件声明为依赖项,而不是在每个规范文件中模拟它们。 现在您的至少一个依赖项依赖于您的新组件,因此您还必须声明您的新组件。

      相反,您应该使用假组件来代替您的真实组件。在您的示例中,您正在测试 SampleComponent。它应该是您拥有的唯一真正的声明。其他一切都应该是伪造的。

      这是一个如何伪造 AccessDeniedComponent 的示例

      @Component({
        selector: 'app-access-denied',
        template: `<div>Access Denied</div>`,
      })
      export class FakeAccessDeniedComponent{
        // any public input/outputs the real one has
        // any public method necessary for your tests
      }
      

      在这种情况下,您将希望伪造的选择器与真实的选择器具有相同的选择器,并且在文件外部使用相同的公共输入/输出/方法。在您的 SampleComponent 规范中,您现在将声明 FakeAccessDeniedComponent 而不是真实的。

      在您的测试本身中,他们应该只期望您已将数据传递到输入、调用方法或侦听输出。任何此类输出事件都应在需要它的测试中伪造。

      要使 AOT 正常工作,您需要将假组件添加到假模块中。那个假模块不需要被任何东西导入。

      假设您已完成所有依赖项,您可能不需要导入尽可能多的模块,因为您只需要导入 SampleComponent 需要工作的模块。您也可能不需要声明尽可能多的组件,因为您只需要 SampleComponent 所依赖的。

      【讨论】:

      • 谢谢韦斯利。我想我明白你在说什么;基本上,如果我正在测试一个组件,我应该将它与其他组件隔离开来,并且不需要导入/声明任何东西。所以我去了其中一个文件tune.component.ts,我发现它没有导入或引用任何其他组件。我尝试从tune.component.spec.ts 的声明中注释行,认为如果该组件没有在被测组件中使用应该没问题,但是注释任何甚至全部(当然TuneComponent 本身除外),仍然给出了关于这些组件的错误。想法?
      • 通常这一切都取决于组件 html 中的 html 元素。如果您引用了 2 或 3 个其他组件,那么您将使用相同的选择器声明假组件,以便您的被测组件知道要绘制什么。话虽如此,我猜你做了一个 fdescribe 只为你正在查看的一个组件运行测试?我肯定会一次拿一个组件。我什至会删除所有声明、模块和提供程序,然后将它们重新添加以修复您看到的错误。如果它仍然想要你的新组件,我会挖掘看看为什么。
      【解决方案3】:
        beforeEach(async(() => {
          TestBed.configureTestingModule({
            declarations: [
              AccessdeniedComponent,
              AppMainComponent,
              AppSubMenuComponent,
              CalibrationComponent,
              ControlComponent,
              DataviewerComponent,
              ExperimentComponent,
              FilemanagerComponent,
              FooterComponent,
              HeaderbarComponent,
              LeftmenuComponent,
              LoginComponent,
              MethodComponent,
              NotfoundComponent,
              SampleComponent,
              TuneComponent,
              TuzGraphComponent
            ],
            imports: [
              AccordionModule,
              AppRoutingModule,
              BlockUIModule,
              CheckboxModule,
              DialogModule,
              DropdownModule,
              FormsModule,
              InputSwitchModule,
              InputTextModule,
              OverlayPanelModule,
              ScrollPanelModule,
              SpinnerModule,
              TableModule
            ]
          }).overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [TuzGraphComponent] } })
            .compileComponents();
        }));
      

      【讨论】:

        猜你喜欢
        • 2017-12-03
        • 2017-03-31
        • 2018-12-27
        • 2019-01-11
        • 2018-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-05
        相关资源
        最近更新 更多