Angular +(Jasmine / Karma) - 错误:非法状态:无法加载指令

时间:2018-01-08 13:28:06

标签: angular jasmine karma-runner

我真的想解决这个错误,互联网上没有任何东西可以帮助我......

lr-categories.component.spec.ts

export function main() {
  describe('LrCategoriesComponent', () => {
    let fixture: ComponentFixture<LrCategoriesComponent>;
    let component: LrCategoriesComponent;
    let de: DebugElement;
    let glService: GeneralLedgeService;
    let lrService: LrService;
    let spy: jasmine.Spy;

    beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          LrComponent,
          LrMappingsComponent,
          LrCategoriesComponent,
        ],
        imports: [
          CommonModule,
          SharedModule,
          LrRoutingModule,
          AgGridModule.withComponents(
            [
              ButtonComponent,
              ColumnHeaderComponent,
              TypeaheadEditorComponent,
              ButtonGroupComponent
            ]
          )
        ],
        providers: [
          LrService,
          { provide: GeneralLedgeService, useClass: MockGeneralLedgeService },
          CompleterService,
        ]
      }).compileComponents().then(() => {
        // initialization
        fixture = TestBed.createComponent(LrCategoriesComponent);
        component = fixture.componentInstance;
        de = fixture.debugElement;

        // Service getters
        glService = de.injector.get(GeneralLedgeService);
        lrService = de.injector.get(LrService);
      });
    }));

    // beforeEach(() => {
    //   // initialization
    //   fixture = TestBed.createComponent(LrCategoriesComponent);
    //   component = fixture.componentInstance;
    //   de = fixture.debugElement;
    //
    //   // Service getters
    //   glService = de.injector.get(GeneralLedgeService);
    //   lrService = de.injector.get(LrService);
    // });

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

错误: enter image description here

  

错误:'未处理承诺拒绝:','非法状态:无法加载   指令LrCategoriesComponent的总结。'

接受任何建议!我现在很绝望!

2 个答案:

答案 0 :(得分:3)

我找到了一个解决方案,我将引导您完成 (解决方案是第3点)

<强> 1。我将初始化内容从.compileComponents().then(() => {...});移到了beforeEach(() => {...});。  (你可以看到它已被评论)

export function main() {
  describe('LrCategoriesComponent', () => {
    let fixture: ComponentFixture<LrCategoriesComponent>;
    let component: LrCategoriesComponent;
    let de: DebugElement;
    let glService: GeneralLedgeService;
    let lrService: LrService;
    let spy: jasmine.Spy;

    beforeEach(async(() => {
      TestBed.configureTestingModule({
        // Module's stuff here
      }).compileComponents();
    }));

    beforeEach(() => {
      // initialization
      fixture = TestBed.createComponent(LrCategoriesComponent);
      component = fixture.componentInstance;
      de = fixture.debugElement;

      // Service getters
      glService = de.injector.get(GeneralLedgeService);
      lrService = de.injector.get(LrService);
    });

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

这给了我以下错误:

  

错误:此测试模块使用组件ToolBarComponent   使用&#34; templateUrl&#34;或&#34; styleUrls&#34;,但它们从未编译过。

此错误是因为SharedModule中声明的某个组件在编译时遇到了问题(实际上,declarations[] SharedModule中的任何组件都发生了这种情况。)

因此,我在导入SharedModule(或其他重型模块)时开始寻找解决spec文件设置的方法。

<强> 2。我找到了一种新方法here

const oldResetTestingModule = TestBed.resetTestingModule;
    beforeAll(done => (async () => {
      TestBed.resetTestingModule();
      TestBed.configureTestingModule({
       // Module's stuff here
      });
      await TestBed.compileComponents();

      // prevent Angular from resetting testing module
      TestBed.resetTestingModule = () => TestBed;
    })().then(done).catch(done.fail));

    afterAll(() => {
      // reinstate resetTestingModule method
      TestBed.resetTestingModule = oldResetTestingModule;
      TestBed.resetTestingModule();
    });

即使最终以一切并且以惊人的速度(5秒vs 20秒之前)这种方法有一个主要的缺点 :每describe()创建一次依赖关系,而不是每次测试。意味着从先前的测试用例继承状态 。我们不想要那个!

3。我回到原点,试图了解并运用更智能的异步逻辑......

- 解决方案 -

beforeEach(done => (async () => {
      TestBed.configureTestingModule({
        // Module's stuff here, including SharedModule
      });
      await TestBed.compileComponents();
    })().then(done).catch(done.fail));

    beforeEach(() => {
      // initialization
      fixture = TestBed.createComponent(LrCategoriesComponent);
      component = fixture.componentInstance;
      de = fixture.debugElement;

      // Service getters
      glService = de.injector.get(GeneralLedgeService);
      lrService = de.injector.get(LrService);
    });

通过使用 async / await 来确保在尝试编译组件之前正确配置模块

有了这个,我设法编译组件,并为每个测试用例场景测试一个干净,新鲜的实例!

答案 1 :(得分:0)

有同样的问题,而我所要做的就是从beforeEach返回承诺,如下所示

beforeEach(() => {  

  return TestBed.configureTestingModule({
        .... setup code
     }).compileComponents().then(() => {
        ...initialization....
    });
  });

});