簡體   English   中英

角度測試異步管道不會觸發可觀察的

[英]Angular testing async pipe does not trigger the observable

我想測試一個使用異步管道的組件。 這是我的代碼:

@Component({
  selector: 'test',
  template: `
    <div>{{ number | async }}</div>
  `
})
class AsyncComponent {
  number = Observable.interval(1000).take(3)
}

fdescribe('Async Compnent', () => {
  let component : AsyncComponent;
  let fixture : ComponentFixture<AsyncComponent>;

  beforeEach(
    async(() => {
      TestBed.configureTestingModule({
        declarations: [ AsyncComponent ]
      }).compileComponents();
    })
  );

  beforeEach(() => {
    fixture = TestBed.createComponent(AsyncComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });


  it('should emit values', fakeAsync(() => {

    tick(1000);
    fixture.detectChanges();
    expect(fixture.debugElement.query(By.css('div')).nativeElement.innerHTML).toBe('0');

});

但是測試失敗了。 似乎出於某種原因,Angular 不會對 Observable 執行。 我缺少什么?

當我嘗試使用do運算符記錄 observable 時,我在瀏覽器控制台中看不到任何輸出。

據我所知,您不能將fakeAsync與異步管道一起使用。 我很想被證明是錯誤的,但我嘗試了一段時間,但什么也做不了。 相反,使用async實用程序(我將其別名為realAsync以避免與async關鍵字混淆)並await Promise 包裝的setTimeout而不是使用tick

import { async as realAsync, ComponentFixture, TestBed } from '@angular/core/testing';

import { AsyncComponent } from './async.component';

function setTimeoutPromise(milliseconds: number): Promise<void> {
  return new Promise((resolve) => { 
    setTimeout(resolve, milliseconds);
  });
}

describe('AsyncComponent', () => {
  let component: AsyncComponent;
  let fixture: ComponentFixture<AsyncComponent>;
  let element: HTMLElement;

  beforeEach(realAsync(() => {
    TestBed.configureTestingModule({
      declarations: [ AsyncComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AsyncComponent);
    component = fixture.componentInstance;
    element = fixture.nativeElement;
    fixture.detectChanges();
  });

  it('should emit values', realAsync(async () => {
    await setTimeoutPromise(1000);
    fixture.detectChanges();
    expect(element.getElementsByTagName('div')[0].innerHTML).toEqual('0');
  }));
});

我遇到了這個問題,我很驚訝沒有人找到任何真正的解決方案。

可能的解決方案

  • 您的模板可能不會在您的測試中呈現,尤其是當您覆蓋它時。 所以,| 異步操作不會觸發。
  • 您使用的fixture.detectChanges()不足以允許模板渲染。 渲染發生在 OnInit 階段之后。 所以請確保您至少使用 fixture.detectChanges 2 次。
  • 也許您有未決的setTimeout操作,例如debounce(100)需要一個tick(100)來解決(在 fakeAsync 測試中)。

干杯

您可以嘗試以下方法:

it('should emit values', (done) => {
  component.number.subscribe((numberElement) => {
    expect(numberElement).toBe(0);

    fixture.detectChanges();

    expect(fixture.debugElement.query(By.css('.number')).nativeElement.innerHTML).toBe('0');

    done();
  });
});

每當觀察到新元素被觀察時,您可以訂閱它並檢查價值和模板是否符合您的期望。

暫無
暫無

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

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