簡體   English   中英

ngOnChanges 未在 Angular 4 單元測試中調用 detectChanges()

[英]ngOnChanges not called in Angular 4 unit test detectChanges()

問題

我有一個按鈕組件,它接受承諾並禁用按鈕,直到承諾解決為止,我想為此功能編寫單元測試。

我的代碼

我的按鈕組件有一個承諾的輸入

  /**
   * A single promise that triggers the busy state until it resolves
   */
  @Input()
  public promise: Promise<any>;

在 ngOnChanges 中,我聆聽承諾

/**
 * Enable button busy state until promise resolves
 */
if (changes && changes.promise && changes.promise.currentValue) {
  this.busyUntilPromiseResolves(changes.promise.currentValue);
}

然后我存儲一系列活動承諾,以便可以傳入多個承諾

  /**
   * Add a promise that will keep the button in a busy state until it resolves
   * @param activityProimise
   */
  private busyUntilPromiseResolves(activityProimise) {
    this.activityPromises.push(activityProimise);
    activityProimise.then(() => {
      this.activityPromises.splice(this.activityPromises.indexOf(activityProimise), 1);
    });
  }

最后在我的模板中,如果數組中有任何承諾,我將禁用該按鈕。

[disabled]="activityPromises.length > 0"

幫我歐比旺

我一直在涉足並嘗試不同的事情來使這項工作,這是我當前的測試代碼不起作用。 基本上,我需要在承諾解決之前檢查按鈕是否被禁用,然后我將想做另一個測試以檢查它在承諾解決后是否重新啟用。

  it('should be disabled when passed a single promise', async((done) => {
    let promise;

    return promise = new Promise(resolve => {
      component.promise = promise;
      fixture.detectChanges();
      expect(buttonElement.disabled).toBe(true);
      return resolve();
    });
  }));

一如既往,任何幫助將不勝感激,謝謝。

這個問題的簡短回答是 ngOnChanges 在單元測試期間不會自動觸發,所以我不得不手動調用它。

  it('should be disabled when passed a single promise', async () => {
    let promise;
    let resolve;

    // should not be disabled here
    expect(buttonElement.disabled).toBe(false);

    // Pass a promise to the component to disable it
    promise = new Promise(r => resolve = r);
    component.ngOnChanges({
      promise: new SimpleChange(null, promise, null)
    });

    fixture.detectChanges();
    expect(buttonElement.disabled).toBe(true);

    // now resolve the promise and make sure it's enabled again.
    promise.then(() => {
      fixture.detectChanges();
      expect(buttonElement.disabled).toBe(false);
    });

    resolve();

  });

在添加該承諾之前,您是否嘗試過斷言?

it('should be disabled when passed a single promise', async(() => {
  let promise;
  // should not be disabledhere
  expect(buttonElement.disabled).toBe(false);
  let resolve;
  const promise = new Promise(r => resolve = r);
  component.promise = promise;
  component.ngOnChanges(); // Call this here, TestBed doesn't know it needs to.
  fixture.detectChanges();
  expect(buttonElement.disabled).toBe(true);

  // now resolve the promise and make sure it's disabled again.
  resolve();
  fixture.detectChanges();
  expect(buttonElement.disabled).toBe(false);
}));

編輯:如評論中所述,您設置該promise屬性的方式不適用於 TestBed,因此它永遠不會調用您的 ngOnChanges() 方法。 可以直接調用它,就像我上面做的那樣。

或者,將您的測試組件包裝在主機組件中:

@Component({
  selector: 'test-component',
  template: `<my-component [promise]="promise"></my-component>`
})
class TestComponent {
  promise;
}

// then use that in your test instead:
const wrapperCmp = TestBed.createComponent(TestComponent);
wrapperCmp.promise = promise; // and check for the button state before and after all the changes.

暫無
暫無

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

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