I'm trying to test the intention of the click event inside an *ngFor but I can't make the test pass.
this is my template:
<div class="container-notification-item" *ngFor="let item of menu.detail">
<div class="notification-item" (click)="getDetailsMessage(item)">
<div class="notification-item__icon" [ngClass]="item.iconStyle">
<span>
<i class={{item.icon}}></i>
</span>
</div>
<div class="notification-item__text text-muted">
<h6 [attr.class]="item.textStyle" [ngStyle]="{'font-size':'1.2rem' }">{{item.title}}</h6>
<div>
<p *ngIf="item.detail" class="detail-title">{{item.detail}}</p>
<p *ngIf="item.time" class="detail-time">
<i class="mdi mdi-clock-outline"></i>
<span>{{item.time}}</span>
</p>
</div>
</div>
</div>
</div>
this is my component:
export class AccountMenuComponent implements DropdownMenuComponentInterface {
@Input() menu: DropdownMenu;
redirect = false;
constructor() { }
getDetailsMessage(item?: DropdownMenuDetail) {
this.redirect = true;
}
getDetailsMessages() {
console.log(this.menu.detail);
}
}
and this is my test:
it('must redirect to view all messages', () => {
fixture.detectChanges();
fixture.whenStable().then(() => {
const elem: DebugElement[] = fixture.debugElement.queryAll(By.css('.notification-item'));
console.log(elem[0]);
elem[0].triggerEventHandler('click', null);
expect(component.redirect).toBeTruthy();
})
})
when I do a console.log of the elem variable I have the html element selected but the test fails.
I think the whenStable is throwing off when karma thinks the test has completed. I was able to get the following to run in a test project.
it('should create the app', (done) => {
// setup that you probably have in a beforeEach
const fixture = TestBed.createComponent(AppComponent);
const component = fixture.componentInstance;
const menu = {detail: ['a','b','c']};
// suggest a fake parent component - but for simplicity I'm just assigning
component.menu = menu;
fixture.detectChanges();
fixture.whenStable().then(() => {
const elem: DebugElement[] = fixture.debugElement.queryAll(By.css('.notification-item'));
console.log(elem[0]);
elem[0].triggerEventHandler('click', null);
// since the value itself is `true`, suggest strongly testing for exactly that
// instead of truthy, which allows more passing conditions
expect(component.redirect).toBe(true);
// call the function passed in to tell it that this test is now done
// because your code is in a promise it runs asynchronously
done();
})
});
Normally you only need whenStable for template forms to finish doing their thing. It can also be used to get past a debounceTime
from rxjs, but I suggest using fakeAsync
and tick
in that case.