1

I want to test the functionality of a button, but that element is not visible on the page because it's under an *ngIf. I would like to set the variable from *ngIf to be truthy in order to be able to display the data. I tried doing it with:

beforeEach(() => {
    fixture = TestBed.createComponent(HeaderComponent);
    component = fixture.componentInstance;
    component.currentUser = {firstName: 'xxx'} as User; // Changing currentUser so it won't be undefined anymore 
    fixture.detectChanges();
  });

but still doesn't work. Here is my component:

<div class="menu-button-container">
    <div class="menu-button" [ngClass]="{'menu-open': isMenuOpen}" (click)="toggleMenu()" *ngIf="currentUser">
        <div class="line-menu-button line-menu-button__top"></div>
        <div class="line-menu-button line-menu-button__middle"></div>
        <div class="line-menu-button line-menu-button__bottom"></div>
    </div>
</div>

and the test I try to run:

it('should open the menu when the button menu is clicked', () => {
    const fixture = TestBed.createComponent(HeaderComponent);
    fixture.detectChanges();
    const menuDebugElement = fixture.debugElement.query(By.css('.menu-button'));
    expect(menuDebugElement).toBeTruthy();
  });

this always fails. If I define the *ngIf rule as *ngIf="currentUser", the test is working. How can I do this variable change from the test? Please advise! Thanks!

2 Answers 2

6

change the value of the currentUser variable:

it('should open the menu when the button menu is clicked', () => {
  const fixture = TestBed.createComponent(HeaderComponent);
  const component = fixture.componentInstance;
  component.currentUser = true;

  fixture.detectChanges();

  const menuDebugElement = fixture.debugElement.query(By.css('.menu-button'));
  expect(menuDebugElement).toBeTruthy();
});

I created an entire test and it works for me

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { TestTComponent } from './test-t.component';
import { By } from '@angular/platform-browser';

fdescribe('TestTComponent', () => {
  let component: TestTComponent;
  let fixture: ComponentFixture<TestTComponent>;

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

  beforeEach(() => {
    fixture = TestBed.createComponent(TestTComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
    component.currentUser = true;

    fixture.detectChanges();

    const menuDebugElement = fixture.debugElement.query(By.css('.menu-button'));
    expect(menuDebugElement).toBeTruthy();
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your comment, but I get the same error as before: Expected null to be truthy.
whenever you change or modify the component class property you need to add this line: fixture.detectChanges();
0

The problem is fixture.detectChanges(); triggers change detaction cycle and when you read value from html component not finished to update itself.

You solve using "whenStable()" function

  it('should open the menu when the button menu is clicked', () => {
    const fixture = TestBed.createComponent(HeaderComponent);
    component.currentUser = true;

    fixture.detectChanges();

    fixture.whenStable()
        .then(() => {
            const menuDebugElement = fixture.debugElement.query(By.css('.menu-button'));
            expect(menuDebugElement).toBeTruthy();
        });
    
  });

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.