简体   繁体   中英

Angular Karma Jasmine test “Can't bind to 'ngIf' since it isn't a known property”

My Karma Jasmine tests of an Angular @Component complain that

ERROR: 'Can't bind to 'ngIf' since it isn't a known property of 'p'.'

When there is that kind of error for the application itself , the fix is to ensure you add BrowserModule to the imports: [] in the @NgModule() of your application module ( app.module.ts ). I indeed have that import (so this question is not a duplicate of that canonical question about "Can't bind to 'ngXXX' since it isn't a known property of 'YYY' ).

This is my test set-up code:

    let component: MyComponent;
    let fixture: ComponentFixture<MyComponent>;

    beforeEach(async () => {
        TestBed.configureTestingModule({
            imports: [
                BrowserModule
            ],
            providers: [
                MyComponent,
                { provide: MyService, useClass: MockMyService }
            ]
        }).compileComponents();
        TestBed.inject(MyService);
        component = TestBed.inject(MyComponent);
        fixture = TestBed.createComponent(MyComponent);
        fixture.detectChanges();
    });

My HTML template says *ngIf , not ngIf or a typo for that, which is another common cause of that error message :

<div class="self">
    <p *ngIf="isLoggedIn() else selfLogin">Logged in as
        {{getUsername()}}</p>
    <ng-template #selfLogin>
    <button id="login" (click)="login()">login</button>
    </ng-template>
</div>

Putting the test module configuration and object injection in separate beforeEach calls (as suggested for a different Angular testing problem ) did not help.

I see you're including the Component in your TestBed providers . Components are normally part of declarations . So, something like this:

    let fixture: ComponentFixture<MyComponent>;
    let component: MyComponent;

    beforeEach(waitForAsync(() => {
        TestBed.configureTestingModule({
            providers: [
                { provide: MyService, useClass: MockMyService }
            ],
            declarations: [
                MyComponent
            ]
        }).compileComponents();
    }));
    beforeEach(() => {
        TestBed.inject(MyService);
        fixture = TestBed.createComponent(SelfComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

You also have a HTML formatting issue for your else declaration:

<div class="self">
    <p *ngIf="isLoggedIn() else selfLogin">Logged in as
        {{getUsername()}}</p>
    <ng-template #selfLogin>
    <button id="login" (click)="login()">login</button>
    </ng-template>
</div>

should be...

*ngIf="isLoggedIn(); else selfLogin"

I got the same error due to me not including the component-under-test in the declarations.

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;

  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [
          MyComponent, // <-What i forgot.
          OtherComponent,
        ],
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM