[英]Getting TypeError pipe is not a function while testing angular component using observable with declarative approach using async
[英]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.