web-dev-qa-db-ja.com

Angularコンポーネントテストで選択オプションをクリックします

私は次のことを試しましたが、どれも機能しない選択ドロップダウンのオプションをクリックしてみました。

_selectEl = fixture.debugElement.query(By.css('#dropdown'));
selectEl.nativeElement.options[3].nativeElement.dispatchEvent(new Event('click'));
selectEl.queryAll(By.css('option'))[3].nativeElement.click();
selectEl.nativeElement.options[3].nativeElement.click();
_

それぞれの後でfixture.detectChanges();を実行して変更検出を実行しますが、要素の値を確認するときは変更されていません。 expect(selectEl.nativeElement.options[selectEl.nativeElement.selectedIndex].textContent).toBe('name2');

これを機能させるために簡単なものがないのですか?

9

ドロップダウンの選択したオプションを変更する方法は、ドロップダウン値を設定してからchangeイベントを送出することです。

あなたはこの答えを参照として使うことができます: 空の値での角度の単体テストの選択onChangeスパイ

あなたの場合、あなたはこのようなことをするべきです:

  const select: HTMLSelectElement = fixture.debugElement.query(By.css('#dropdown')).nativeElement;
  select.value = select.options[3].value;  // <-- select a new value
  select.dispatchEvent(new Event('change'));
  fixture.detectChanges();
11
Ayala

Changeイベントをディスパッチする必要はありません。まず、ドロップダウンのトリガーをクリックする必要があります。これは、selectEl selectEl = fixture.debugElement.query(By.css('#dropdown'))であると想定しています。

_selectEl.click();
fixture.detectChanges();
_

DetectChangesの後、ドロップダウンを開く必要があります。この後で初めて、フィクスチャーからオプションを取得できるようになります。

オプションを取得できる唯一の方法は、const selectOptions = fixture.debugElement.queryAll(By.css('.select-option'));を実行することです。ここで、「select-option」は、オプションに付けたクラスです。私のプロジェクトではmat-selectを使用しているので、これはそれが原因である可能性があります。

selectOptions[0].nativeElement.click();を実行すると、最初のオプションをクリックできます。その後、再度fixture.detectChanges()を呼び出す必要があります。これでオプションが選択されました!

selectEl.innerText.trim()を実行することで、現在選択されている値を取得できました。これが最善の方法かどうかはわかりませんが、動作します。トリムは空白を削除するために使用されます。

7
Emmy

私はエミーの答えを少し拡張しました。マテリアルドロップダウンを選択するための実用的な「ヘルパー」メソッドを次に示します。

import { By } from '@angular/platform-browser';

export default class TestUtils {
  static selectDropdown(id: string, fixture: any): void {
    const select = fixture.debugElement.query(By.css(`#${id}`)).nativeElement;
    select.click();
    fixture.detectChanges();
    const selectOptions = fixture.debugElement.queryAll(By.css(`.${id}Option`));
    selectOptions[5].nativeElement.click();
    fixture.detectChanges();
  }
}

これにより、選択したいドロップダウン(IDによる)と選択したいインデックスを指定できます。このメソッドの唯一の警告は、ドロップダウンのマットオプション要素にクラスを追加する必要があることです。例:

<mat-option *ngFor="let trim of trims" value="{{trim}}" class="trimDropdownOption">{{trim}}</mat-option>

Mat-optionのクラスに 'Option'が追加されたIDが含まれていることを確認してください。

これは、エミーの回答の問題を解決します。単一のフォームに複数のドロップダウンがある場合、クリックするマットオプションを指定できます。

上記の拡張メソッドは、テストで次のように参照することで利用できます。

TestUtils.selectDropdown('yearDropdown', 1, fixture);
expect(fixture.componentInstance.onYearChange).toHaveBeenCalled();
0
Nate