Angular Karma Jasmine 错误:非法状态:无法加载指令摘要

Posted

技术标签:

【中文标题】Angular Karma Jasmine 错误:非法状态:无法加载指令摘要【英文标题】:Angular Karma Jasmine Error: Illegal state: Could not load the summary for directive 【发布时间】:2018-01-17 00:08:09 【问题描述】:

我正在开发一个github repository(使用 angular 7 和 angular-cli),并且我在 master 分支中使用 Karma 和 Jasmine 进行了一些测试。

现在我正在尝试添加延迟加载功能,问题是,之前通过的测试现在没有通过。这很有趣,因为只有延迟加载模块中的测试失败了......

这是代码和错误:

import async, TestBed from '@angular/core/testing';
import APP_BASE_HREF from '@angular/common';
import AppModule from '../../app.module';
import HeroDetailComponent from './hero-detail.component';

describe('HeroDetailComponent', () => 
  beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: [AppModule
      ],
      providers: [
        provide: APP_BASE_HREF, useValue: '/'
      ],
    ).compileComponents();
  ));

  it('should create hero detail component', (() => 
    const fixture = TestBed.createComponent(HeroDetailComponent);
    const component = fixture.debugElement.componentInstance;
    expect(component).toBeTruthy();
  ));
);

错误是这样的:

Chrome 58.0.3029 (Mac OS X 10.12.6) HeroDetailComponent should create hero detail component FAILED
    Error: Illegal state: Could not load the summary for directive HeroDetailComponent.
        at syntaxError Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:1690:22)
        at CompileMetadataResolver.getDirectiveSummary Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:15272:1)
        at JitCompiler.getComponentFactory Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler.es5.js:26733:26)
        at TestingCompilerImpl.getComponentFactory Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/compiler/@angular/compiler/testing.es5.js:484:1)
        at TestBed.createComponent Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/core/@angular/core/testing.es5.js:874:1)
        at Function.TestBed.createComponent Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/@angular/core/@angular/core/testing.es5.js:652:1)
        at UserContext.it Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/src/app/heroes/hero-detail/hero-detail.component.spec.ts:18:29)
        at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/zone.js:391:1)
        at ProxyZoneSpec.onInvoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/proxy.js:79:1)
        at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke Users/ismael.ramos.silvan/WebstormProjects/angular4-example-app/~/zone.js/dist/zone.js:390:1)

您可以查看整个项目,如果您需要了解更多详细信息。

更新:添加了这样的声明:

beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: [
        AppModule
      ],
      declarations: [HeroDetailComponent],
      providers: [
        provide: APP_BASE_HREF, useValue: '/'
      ],
    ).compileComponents();
  ));

现在,出现了新的错误:

The pipe 'translate' could not be found ("<h1 class="section-title">[ERROR ->]'heroDetail' | translate</h1>
    <md-progress-spinner *ngIf="!hero"
                         class="progre"): ng:///DynamicTestModule/HeroDetailComponent.html@0:28
    Can't bind to 'color' since it isn't a known property of 'md-progress-spinner'.

还有更多...就像所有来自角度材料的指令和组件,并且似乎不包括来自 ngx-translate/core 的管道转换...

【问题讨论】:

你不需要声明组件来测试它,你只需要稍微不同地设置测试台:github.com/angular/angular/issues/17477#issuecomment-510397690 请张贴self answer,而不是“更新:最终解决方案”,以便您的问题与解决方案清楚地划定,并且解决方案与所有其他可能的解决方案一起受到赞成/反对票的影响。 我已将您问题的答案添加为actual answer。如果您想按照提示自己执行此操作,请告诉我,我将删除我的 wiki 【参考方案1】:

您在没有先声明组件的情况下将HeroDetailComponent 传递给TestBed.createComponent()

TestBed.configureTestingModule(
  imports: [AppModule,
     CommonModule,
     FormsModule,
     SharedModule,
     HeroRoutingModule,
     ReactiveFormsModule
  ],
  providers: [
    provide: APP_BASE_HREF, useValue: '/'
  ],
  declarations: [HeroDetailComponent]
).compileComponents();

希望对你有帮助。


针对测试中的以下错误进行更新:添加了更多导入(只需将您的 HeroModule 作为蓝图,因为这基本上就是您想要导入和提供的内容)。

【讨论】:

如果我添加该声明,则会出现更多错误。我更新了信息,你可以在上面看到。 好吧,但这就是你摆脱这个错误的方法。以下错误可能是您的测试设置的另一个问题。 接下来会出现什么错误? 找不到管道'translate' ("

[ERROR ->]'heroDetail' | translate

别忘了,这是因为它是一个延迟加载模块。因为我的其他测试没有失败......【参考方案2】:

您缺少声明,您需要将正在测试的类添加到声明中。

declarations: [component]

【讨论】:

在我的例子中,我将 TestBed 的配置从一个组件复制到了新组件,然后,我没有包含被测组件。【参考方案3】:

我和我的同事遇到了这个问题,但修复方法与互联网上的其他任何东西都不同。

我们使用的是 Visual Studio Code,文件夹名称不区分大小写。因此,我们要求每个人都使用小写命名约定,但最终大写名称进入了源代码管理。我们以迂回的方式重命名了它,一切都很好。

一个月后,我的同事开始进行特定的单元测试来解决此错误消息。只有他的电脑在那次测试中坏了。我们从字面上注释掉了所有可能影响测试的代码,但我们仍然得到错误。最后,我全局搜索该类,我们发现文件夹名称已恢复为大写名称。我们将其重命名为小写名称,我可以添加没有识别出任何待处理的更改...,并且测试成功了。

让这成为遵循风格指南的教训。 :)

为清楚起见,修复类似于将文件夹名称 FOO 更改为 foo

【讨论】:

【参考方案4】:

由于缺少在 TestBed 配置提供者的声明和服务中添加组件而引发的此类错误。

beforeEach(() => 
    TestBed.configureTestingModule(
      imports: [RouterTestingModule.withRoutes([
         path: 'home', component: DummyComponent ,
         path: 'patients/find', component: DummyComponent 
      ])],
      declarations: [RoutingComponent, DummyComponent,BreadcrumbComponent],
      providers : [BreadCrumbService]
    );

【讨论】:

【参考方案5】:

您必须以正确的方式导入组件HeroDetailComponent注意,即使是字母的大小写也是路径中的问题。即('@angular/forms' 是正确的,BUT'@angular/Forms' 不是。

【讨论】:

【参考方案6】:

对于那些对此仍有疑问的人 - 我阅读了一个单独的 github 问题,其中讨论了 Angular 团队对 beforeEach 回调函数所做的更改。

这是我所做的:

beforeAll(async(() => 
    TestBed.configureTestingModule(
        declarations: [BannerNotificationComponent]
    ).compileComponents()

    fixture = TestBed.createComponent(BannerNotificationComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
));

使用 beforeAll 可以解决问题。希望这对其他人有所帮助,因为我花了大约一天的时间才解决了这个晦涩的错误。

【讨论】:

就我而言,使用beforeAll 实际上会产生问题。【参考方案7】:

如果您想在不编译的情况下测试组件,那么您可以将其声明为提供者:

beforeEach(() => 
  TestBed.configureTestingModule(
    // provide the component-under-test and dependent service
    providers: [
      WelcomeComponent,
       provide: UserService, useClass: MockUserService 
    ]
  );
  // inject both the component and the dependent service.
  comp = TestBed.get(WelcomeComponent);
  userService = TestBed.get(UserService);
);

见:https://angular.io/guide/testing#component-test-basics

【讨论】:

【参考方案8】:

我在测试套件中导入了错误的模块!更正导入的模块修复了此错误。

【讨论】:

【参考方案9】:

没有问题的答案复制了

问题是 HeroesModule 没有被导入任何地方。 这是可行的,因为 HeroesModule 声明了 HeroDetailComponent,这是最初的问题

import async, TestBed from '@angular/core/testing';
import APP_BASE_HREF from '@angular/common';
import AppModule from '../../app.module';
import HeroDetailComponent from './hero-detail.component';
import HeroesModule from '../heroes.module';

describe('HeroDetailComponent', () => 
  beforeEach(async(() => 
    TestBed.configureTestingModule(
      imports: [
        AppModule,
        HeroesModule
      ],
      providers: [
        provide: APP_BASE_HREF, useValue: '/'
      ],
    ).compileComponents();
  ));

  it('should create hero detail component', (() => 
    const fixture = TestBed.createComponent(HeroDetailComponent);
    const component = fixture.debugElement.componentInstance;
    expect(component).toBeTruthy();
  ));
);

【讨论】:

以上是关于Angular Karma Jasmine 错误:非法状态:无法加载指令摘要的主要内容,如果未能解决你的问题,请参考以下文章

在 Jasmine/Karma 测试中使用 mockError 时,apollo-angular 会抛出错误

Angular - Jasmine/karma - 订阅 lambda 表达式未执行

使用 jasmine 和 karma 进行单元测试时形成数组错误

使用 Angular 和 Jasmine/Karma 的私有方法进行测试和代码覆盖

使用 Jasmine 和 Karma 进行角度单元测试时出错

Angular2材料'md-icon'不是Karma / Jasmine的已知元素