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.
What does "Can't bind to 'x' since it isn't a known property of 'y'" mean? link. This error often means that you haven't declared the directive "x" or haven't imported the NgModule to which "x" belongs. Perhaps you declared "x" in an application sub-module but forgot to export it.
ngFor is not a known property would mean for whatever reason, ngFor cannot be recognized in the application. However, the real problem was that ngFor was recognised but the syntax of ngFor was wrong. Anyway, let's hope Angular team improves their logging in future updates.
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,
],
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With