Angular 2 Karma Test 'nombre del componente' no es un elemento conocido

105

En AppComponent, estoy usando el componente de navegación en el código HTML. La interfaz de usuario se ve bien. Sin errores al hacer ng saque. y no hay errores en la consola cuando miro la aplicación.

Pero cuando ejecuté Karma para mi proyecto, hay un error:

Failed: Template parse errors: 
'app-nav' is not a known element:
1. If 'app-nav' is an Angular component, then verify that it is part of this module.
2. If 'app-nav' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.

En mi app.module.ts :

Ahi esta:

import { NavComponent } from './nav/nav.component';

También está en la parte de declaraciones de NgModule

@NgModule({
  declarations: [
    AppComponent,
    CafeComponent,
    ModalComponent,
    NavComponent,
    NewsFeedComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    JsonpModule,
    ModalModule.forRoot(),
    ModalModule,
    NgbModule.forRoot(),
    BootstrapModalModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

Estoy usando el NavComponenten miAppComponent

app.component.ts

import { Component, ViewContainerRef } from '@angular/core';
import { Overlay } from 'angular2-modal';
import { Modal } from 'angular2-modal/plugins/bootstrap';
import { NavComponent } from './nav/nav.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Angela';
}

app.component.html

<app-nav></app-nav>
<div class="container-fluid">
</div>

He visto una pregunta similar, pero la respuesta en esa pregunta dice que deberíamos agregar NgModule en el componente de navegación que tiene una exportación en eso, pero obtengo un error de compilación cuando hago eso.

También hay: app.component.spec.ts

import {NavComponent} from './nav/nav.component';
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
Angela P
fuente
Es probable que le falte una importación en su archivo de especificaciones. Supongo que la prueba de especificaciones está en app.spec.ts, por lo que querrá hacerlo import { NavComponent }en sus spec.ts
Z. Bagley
1
es importado. Me faltaba la parte de la declaración
Angela P
1
Importar y declarar el componente personalizado dentro de app.component.spec.ts funcionó para mí, ¡gracias chicos!
ENDEESA

Respuestas:

161

Debido a que en las pruebas unitarias desea probar el componente mayormente aislado de otras partes de su aplicación, Angular no agregará las dependencias de su módulo como componentes, servicios, etc. de forma predeterminada. Por lo tanto, debe hacerlo manualmente en sus pruebas. Básicamente, tienes dos opciones aquí:

A) Declare el NavComponent original en la prueba

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          NavComponent
        ]
      }).compileComponents();
    }));

B) Simulacros del NavComponent

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          MockNavComponent
        ]
      }).compileComponents();
    }));

// it(...) test cases 

});

@Component({
  selector: 'app-nav',
  template: ''
})
class MockNavComponent {
}

Encontrarás más información en la documentación oficial .

Kim Kern
fuente
Gracias ... ¡¡Funcionó para mí !!
Hidayt Rahman
1
Gracias por esto. Me he encontrado con el problema de tener que importar varios componentes y módulos hasta el punto en que tiene mucho más sentido simplemente importar el AppModuleen la configuración de TestBed. ¿Recomendaría usted no hacerlo?
mcheah
@jonathan ¿tal vez el componente que declaró tiene dependencias propias? En una prueba unitaria, es mejor usar simulacros.
Kim Kern
8

También puedes usar NO_ERRORS_SCHEMA

describe('AppComponent', () => {
beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [
      AppComponent
    ],
    schemas: [NO_ERRORS_SCHEMA]
  }).compileComponents();
}));

https://2018.ng-conf.org/mocking-dependencies-angular/

Adrian
fuente
3
¿Hay problemas potenciales que surgirán de esto? Parece una solución conveniente, pero ¿hay algún error importante que pueda ser anulado?
mcheah
8
Esto es lo que dicen los documentos de prueba : "El NO_ERRORS_SCHEMA también evita que el compilador le diga acerca de los componentes faltantes y los atributos que omitió inadvertidamente o escribió mal. Podría perder horas persiguiendo errores fantasmas que el compilador habría detectado en un instante".
Kim Kern
5
definitivamente no va a introducir un comportamiento implícito adicional en sus pruebas unitarias: el uso de NO_ERRORS_SCHEMA lo alentará a colocar las dependencias en la zona 'gris' entre 'burlado' y 'extraído'. cualquier cambio en esas dependencias puede potencialmente desencadenar la ruptura de pruebas unitarias aparentemente no relacionadas - no es bueno
averasko
0

Para mí, la importación del componente en el padre resolvió el problema.

describe('AppComponent', () => {
  beforeEach(async(() => {
      TestBed.configureTestingModule({
        declarations: [
          AppComponent,
          NavComponent
        ]
      }).compileComponents();
    }));

Agregue esto spec of the parentdonde se usa este componente.

Kailas
fuente
0

Una razón más es que puede haber múltiples .compileComponents()para beforeEach()en su caso de prueba

por ejemplo

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [TestComponent]
  }).compileComponents();
}));

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [HttpClientModule],
    declarations: [Test1Component],
    providers: [HttpErrorHandlerService]
  }).compileComponents();
});
Devaarth
fuente
0

Paso 1: cree stubs al comienzo del archivo de especificaciones.

@Component({selector: 'app-nav', template: ''})
class NavComponent{}

Paso 2: agregue stubs en las declaraciones del componente.

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule
  ],
  declarations: [
    AppComponent,
    NavComponent
  ],
}).compileComponents();
Yuvraj Patil
fuente