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


98

我正在开发github存储库(使用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转换的管道...

更新:最终解决方案

问题在于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();
  }));
});

1
您无需声明要测试的组件,只需要稍微不同地设置测试平台即可:github.com/angular/angular/issues/17477#issuecomment-510397690
Stevanicus

Answers:


179

您传递HeroDetailComponentTestBed.createComponent()未先声明组件:

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

希望能帮助到你。


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


如果添加该声明,则会出现更多错误。我更新了信息,您可以在上方看到它。
ismaestro

1
好吧,但这就是您摆脱这个错误的方法。跟随错误可能是测试设置的另一个问题。
lexith

接下来会发生什么错误?
lexith '17

找不到管道“翻译”(“ <h1 class =” section-title“> {{[错误->]'heroDetail'| translation}} </ h1> <md-progress-spinner * ngIf =”!英雄”类=‘逐行’):NG:///DynamicTestModule/HeroDetailComponent.html@0:28不能绑定到‘颜色’,因为它不是‘MD-进步微调’的已知属性。
ismaestro

而且请不要忘记,这是因为它是一个延迟加载模块而发生的。因为我进行的其他测试不会失败...
ismaestro


2

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

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

2

我和我的同事都遇到了这个问题,但解决方法与互联网上的其他工具完全不同。

我们正在使用Visual Studio Code,并且文件夹名称不区分大小写。因此,我们要求每个人都使用小写字母命名约定,但最终在源代码管理中使用了大写字母。我们以一种环岛的方式将其重命名,一切都很好。

一个月后,我的同事开始获取特定的单元测试,以打破此错误消息。只有他的计算机在该测试上损坏。我们从字面上注释掉了所有可能影响测试的代码,但仍然出现错误。最后,我全局搜索了该类,然后我们意识到文件夹名称已还原为大写名称。我们将其重命名为小写名称,没有可能识别的未决更改可能会添加...,并且测试成功了。

让这成为遵循样式指南的课程。:)

为了清楚起见,此修复类似于将文件夹名称更改FOOfoo


1

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


1

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

这是我所做的:

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

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

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


0

如果要在不编译的情况下测试组件,则可以将其声明为提供程序:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.