Angular Karma Jasmine Error: estado ilegal: no se pudo cargar el resumen de la directiva

98

Estoy desarrollando un repositorio de github (con angular 7 y angular-cli), y tengo algunas pruebas con Karma y Jasmine trabajando en la rama maestra.

Ahora estoy tratando de agregar la función de carga diferida, la cosa es que las pruebas que antes pasaron, ahora no lo hacen. Es gracioso porque solo fallan las pruebas del módulo de carga diferida ...

Aquí está el código y el error:

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();
  }));
});

El error es este:

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)

Puedes ver el proyecto completo, para más detalles si lo necesitas.

ACTUALIZACIÓN: declaración agregada como esta:

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

Ahora, aparecen nuevos errores:

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'.

Y más ... es como todas las directivas y componentes de material angular, y la traducción de tubería de ngx-translate / core no parece estar incluida ...

ACTUALIZADO: SOLUCIÓN FINAL

El problema fue que HeroesModule no se importó a ningún lado. Esto funciona, porque HeroesModule declara HeroDetailComponent, que fue el problema inicial :

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();
  }));
});
ismaestro
fuente
1
No necesita declarar el componente para probarlo, solo necesita configurar el banco de pruebas de manera ligeramente diferente: github.com/angular/angular/issues/17477#issuecomment-510397690
Stevanicus

Respuestas:

179

Pasó HeroDetailComponenta TestBed.createComponent()sin declarar el componente primero:

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

Espero eso ayude.


Actualización para los siguientes errores en su prueba: se agregaron algunas importaciones más (solo tome su HeroModule como modelo porque eso es básicamente lo que desea importar y proporcionar).

Lexith
fuente
Si agrego esa declaración, aparecen más errores. Actualicé la información, puedes verla arriba.
ismaestro
1
Bueno, pero así es como te deshaces de este error. Los siguientes errores pueden ser otro problema con la configuración de la prueba.
Lexith
¿Qué error viene después?
Lexith
No se pudo encontrar la tubería 'translate' ("<h1 class =" section-title "> {{[ERROR ->] 'heroDetail' | translate}} </h1> <md-progress-spinner * ngIf ="! hero "class =" progre "): ng: ///DynamicTestModule/HeroDetailComponent.html@0: 28 No se puede vincular a 'color' porque no es una propiedad conocida de 'md-progress-spinner'.
ismaestro
Y no olvide que esto sucede porque es un módulo de carga diferida. Porque las otras pruebas que tengo no fallan ...
ismaestro
8

Le faltan las declaraciones, debe agregar la clase que se está probando en las declaraciones.

declarations: [component]
Akash Yellappa
fuente
En mi caso, copié la configuración de TestBed de un componente al nuevo y, luego, no incluí el componente bajo prueba.
Tonatio
2

Este tipo de error surgió debido a la falta de un componente agregado en las declaraciones y servicios en el proveedor de configuración de TestBed.

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

Mi compañero de trabajo y yo tuvimos este problema, pero la solución fue muy diferente a cualquier otra cosa en Internet.

Estamos usando Visual Studio Code y los nombres de las carpetas no distinguen entre mayúsculas y minúsculas. Por eso, les pedimos a todos que usaran una convención de nomenclatura en minúsculas, pero finalmente un nombre en mayúsculas entró en el control de fuente. Le cambiamos el nombre, de forma indirecta, y todo salió bien.

Un mes después, mi compañero de trabajo comenzó a obtener una prueba unitaria específica para romper con este mensaje de error. Solo su computadora se rompió en esa prueba. Literalmente comentamos todo el código que podría estar afectando la prueba y aún obtuvimos el error. Finalmente, busqué globalmente la clase y nos dimos cuenta de que el nombre de la carpeta había vuelto al nombre en mayúsculas. Lo cambiamos de nuevo a un nombre en minúsculas, sin que se reconocieran cambios pendientes, podría agregar ..., y la prueba funcionó.

Que sea una lección para seguir las guías de estilo. :)

Para mayor claridad, la solución fue similar a cambiar el nombre de la carpeta FOOa foo.

christo8989
fuente
1

debe importar el componente HeroDetailComponent de la manera correcta. Tenga en cuenta que incluso el caso de las letras es materia en los caminos. es decir ('@ angular / forms' es correcto, PERO '@ angular / Forms' no lo es.

sami
fuente
1

Para aquellos que todavía tienen problemas con esto, leí un problema de github separado que discutía los cambios que hizo el equipo de Angular en la función de devolución de llamada beforeEach.

Aquí esta lo que hice:

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

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

Usar beforeAll soluciona el problema. Espero que esto ayude a otros, ya que me tomó alrededor de un día resolver este error oscuro.

Adam P
fuente
0

Si desea probar un componente sin compilarlo, puede declararlo como proveedor:

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);
});

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

Stevanicus
fuente