1
votes

Trying to get my select menus change event to fire correctly with the correct value. It seems to be firing but the value is not changing.

I have this select menu in my component:

<select id="seasonDropDown" style="width:200px;height: 36px;" aria-label="Select a Season" (change)="changeSeason($event.target.value)">
        <option *ngFor="let item of seasons" [value]="item.id" [selected]="item.id === seasonId">Season {{item.id}}</option>
    </select>

I have this change event:

  public changeSeason(seasonId: number) {
    this.test = 'blah';  //for testing sake
    console.log('change season ' + seasonId)
    this.seasonId = seasonId;
    this.notify.emit(this.seasonId);
  }

I have tried testing it like the code below but commponent.seasonId never changes from its default value. It should get changed in changeSeason method. I know the method is firing because when I test expect(component.test).toEqual('blah') it will pass:

    it('should emit new season on change event', fakeAsync(() => {

        let select = fixture.debugElement.query(By.css('#seasonDropDown')).nativeElement;

        select.value = 2;
        select.selectedValue = 2;

        fixture.detectChanges();

        select.dispatchEvent(new Event('change'));
        tick();

        fixture.detectChanges();


        expect(component.seasonId).toEqual(2);
        //expect(component.test).toEqual('blah');  this will pass so I know the 
        //changeSeason event is actually getting called 
  }));
1

1 Answers

5
votes

Before grabbing select element in your test you should run

fixture.detectChanges();

to have properly linked html elements to your component and its event handlers. Have a look at my reproduction on stackblitz. Here's just the test:

it('should emit new season on change event', () => {
  fixture.detectChanges();
  let select = fixture.debugElement.query(By.css('#seasonDropDown')).nativeElement as HTMLSelectElement;

  select.selectedIndex = 1;  // {id:2}
  select.dispatchEvent(new Event('change'));
  fixture.detectChanges();

  expect(+component.seasonId).toEqual(2);
  expect(component.test).toBe('blah');
});

Note that I used selectedIndex property of HTMLSelectElement to select 2nd option to simulate a changed selection (together with distachEvent(...)).

I hope this helps someone.