簡體   English   中英

如何對包含 ng-select 的表單進行單元測試?

[英]How can I unit test a form containing ng-select?

我創建了一個 Angular 表單組件,它使用<ng-select>作為 HTML <select>元素的替代品。 現在我想對我的組件進行單元測試。 為了測試組件邏輯,我有一些方法可以在 DOM 中找到 HTML 元素並檢查或修改它們的值。 這適用於原生 HTML 元素。 但是<ng-select>很難。

我可以用這樣的東西找到當前值,但感覺就像一個非常脆弱的解決方案。

document.querySelector("ng-select[formControlName=country] .ng-value .ng-value-label").innerText

以及如何更改選擇? 使用標准輸入組件,您可以設置值,然后觸發輸入事件。 <ng-select/>里面有一個<input type="text" role="combobox"> > ,但是改變它的值似乎不會影響 FormControl 的值。

我不是在嘗試測試 ng-select,但我確實需要驗證我的組件是否對選擇更改做出了適當的反應。 運行自動化集成測試時,還需要在 UI 中進行選擇。

我偶然發現了同樣的問題。 克里斯是對的,ng-select 源提供了一些測試功能,我只是從中構建了這個文件。 這有望讓 select 成為由 css 選擇器查詢的 select 的選項更容易一些。 請讓我知道這對你有沒有用。

import { DebugElement } from '@angular/core';
import { ComponentFixture, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

export class TestsErrorHandler {}

export enum KeyCode {
  Tab = 9,
  Enter = 13,
  Esc = 27,
  Space = 32,
  ArrowUp = 38,
  ArrowDown = 40,
  Backspace = 8
}

export function tickAndDetectChanges(fixture: ComponentFixture<any>) {
  fixture.detectChanges();
  tick();
}

export function selectOption(fixture, selector: string, arrowDowns: number) {
  triggerKeyDownEvent(getNgSelectElement(fixture, selector), KeyCode.Space); // open
  tickAndDetectChanges(fixture); // need to tick and detect changes
  for (let i = 0; i < arrowDowns; i++) {
    triggerKeyDownEvent(getNgSelectElement(fixture, selector), KeyCode.ArrowDown);
  }
  tickAndDetectChanges(fixture); dropdown fully inits after promise is resolved
  triggerKeyDownEvent(getNgSelectElement(fixture, selector), KeyCode.Enter); // select
  fixture.detectChanges();
}

export function getNgSelectElement(fixture: ComponentFixture<any>, selector: string): DebugElement {
  return fixture.debugElement.query(By.css(selector));
}

export function triggerKeyDownEvent(element: DebugElement, which: number, key = ''): void {
  element.triggerEventHandler('keydown', {
    which: which,
    key: key,
    preventDefault: () => { },
  });
}

您可以使用 Harness (MatselectHarness) 與 Angular Material 組件進行交互。 這將使測試更加健壯:

 it('should have 20 countries in the select box', async () => {
    ...
    const select = await loader.getHarness(MatSelectHarness.with(MatSelectHarness);
    //Click the select element host
    (await selectHarness.host()).click();
    const actual = (await selectHarness.getOptions()).length;
    expect(actual).toBe(20);
  });

Select 一個值(來自 angular 文檔的示例代碼):

it('should switch to bug report template', async () => {
    expect(fixture.debugElement.query('bug-report-form')).toBeNull();
    const select = await loader.getHarness(MatSelect);
    await select.open();
    const bugOption = await select.getOption({text: 'Bug'});
    await bugOption.click();
    expect(fixture.debugElement.query('bug-report-form')).not.toBeNull();
  });

請參閱:使用組件線束

另一種方法是將邏輯移動到服務中。 可以輕松地對服務進行單元測試。

答案是查看ng-select 源代碼並查看測試代碼。 有幾個測試示例可以更改 select 值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM