0

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.