angularunit-testingjasmineangular-unit-test

Unit testing in Angular - property value not updating


I have simple function which shows and hides dropdown menu on click event. Here is HTML code

<div (click)="toggleDropdown()" id="game-category">Show/Hide menu</div>
<div class="relative">
   <app-category *ngIf="isShown" [filtersList]="categories">
   </app-category>
</div>

The function sets an opposite value to the property value of a component.

isShown = false; 

toggleDropdown(): void {
     this.isShown = !this.isShown;
}

Everything works fine, but when I run the tests then I get an error. Here is the testing code:

describe('CreateGameComponent', () => {

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

    beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        CommonModule,
      ],
      declarations: [CreateGameComponent],
      providers: [RequestService, SessionService, AdminService],
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(CreateGameComponent);
        component = fixture.componentInstance;
        component.isShown = false;
        fixture.detectChanges();
      });
   });

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

   it('should check if toggleDropdownwas called', fakeAsync(() => {
      spyOn(component, 'toggleDropdown');
      let button =
      fixture.debugElement.nativeElement.querySelector('#game-category');
      button.click();
      tick();
      fixture.detectChanges();

      expect(component.toggleDropdown).toHaveBeenCalled();
      expect(component.isShown).toBe(true, 'isShown has not changed');
   }));
      
      
 })

After triggering click event isShown property is not changing it's value. Any help is appreciated. Thanks!


Solution

  • when you do spyOn(component, 'toggleDropdown');, it mocks the method, its content becomes empty, and is not executed anymore. You have to add spyOn(component, 'toggleDropdown').and.callThrough(), so the method is actually called.