ChatGPT解决这个技术问题 Extra ChatGPT

Angular 2 Karma Test 'component-name' is not a known element

In the AppComponent, I'm using the nav component in the HTML code. The UI looks fine. No errors when doing ng serve. and no errors in console when I look at the app.

But when I ran Karma for my project, there is an 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.

In my app.module.ts:

there is:

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

It is also in the declarations part of NgModule

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

I'm using the NavComponent in my AppComponent

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>

I have seen a similar question, but the answer in that question says we should add NgModule in the nav component that has a export in that, but I'm getting compile error when I do that.

There is also: app.component.spec.ts

import {NavComponent} from './nav/nav.component';
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
You're likely missing an import in your spec file. I'm assuming the spec test is on app.spec.ts, so you'll want to import { NavComponent } in your spec.ts
it's imported. I was missing the declaration part
Importing and declaring the custom component inside app.component.spec.ts worked for me, thanks guys!

K
Kim Kern

Because in unit tests you want to test the component mostly isolated from other parts of your application, Angular won't add your module's dependencies like components, services, etc. by default. So you need to do that manually in your tests. Basically, you have two options here:

A) Declare the original NavComponent in the test

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

B) Mock the NavComponent

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

// it(...) test cases 

});

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

You'll find more information in the official documentation.


Thanks...Worked for me!!
Thanks for this. I've run into the issue of having to import multiple components and modules to the point where it makes far more sense to just import the AppModule in the TestBed configuration. Would you recommend against this?
@jonathan maybe the component you declared has dependencies of its own? In a unit test, it's better to use mocks.
Is there any way to configure the logging to show test names or any relevant info that shows which spec is causing these messages?
Documentation has moved to angular.io/guide/….
K
Katherine R

You can also use NO_ERRORS_SCHEMA

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

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


are there any potential issues that will arise out of this? It seems like a convenient fix but are there any important errors that will be quashed by this?
This is what the testing docs say: "The NO_ERRORS_SCHEMA also prevents the compiler from telling you about the missing components and attributes that you omitted inadvertently or misspelled. You could waste hours chasing phantom bugs that the compiler would have caught in an instant."
you definitely don't wont to introduce extra implicit behavior into your unit tests: using NO_ERRORS_SCHEMA will encourage you to put dependencies into the 'grey' zone of between 'mocked' and 'pulled in'. any changes to those dependencies can potentially trigger breaking of seemingly unrelated unit tests -- no good
K
Kailas

For me importing the component in the parent resolved the issue.

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

Add this in spec of the parent where this component is used.


S
Spikolynn

One more reason is that there can be multiple .compileComponents() for beforeEach() in your test case

for e.g.

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

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

Y
Yuvraj Patil

Step 1: Create stubs at beginning of spec file.

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

Step 2: Add stubs in component's declarations.

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

G
GoTo

Another source for this error are the tests for the parent component, app-root, that include the tag of this component, app-nav.

Even though the message is about app-nav, the child component, the fix should be added in the tests of app-root, the parent component.

The fix can be a mock:

app.component.spec.ts:

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

What happens is that you create the root component, with it's tests, they pass. Latter on you add the child component in the root component tag and now you have to update the root component tests even if you just added a tag in the template.

Also the message doesn't say which test fails and from the message you might be led to believe that it's the child component's tests, when in fact they are the parent's tests.


E
Experimenter

If you create a stub and still get the same error it might be because of --watch mode on. Try to stop it and run again.