Javascript 角度测试异步管道不会触发可观察到的

Javascript 角度测试异步管道不会触发可观察到的,javascript,angular,testing,Javascript,Angular,Testing,我想测试一个使用异步管道的组件。这是我的代码: @Component({ selector: 'test', template: ` <div>{{ number | async }}</div> ` }) class AsyncComponent { number = Observable.interval(1000).take(3) } fdescribe('Async Compnent', () => { let componen

我想测试一个使用异步管道的组件。这是我的代码:

@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');

});
@组件({
选择器:“测试”,
模板:`
{{number}异步}
`
})
类异步组件{
数字=可观察。间隔(1000)。取(3)
}
fdescribe('异步组件',()=>{
let组件:异步组件;
let夹具:组件夹具;
之前(
异步(()=>{
TestBed.configureTestingModule({
声明:[异步组件]
}).compileComponents();
})
);
在每个之前(()=>{
fixture=TestBed.createComponent(异步组件);
组件=fixture.componentInstance;
fixture.detectChanges();
});
它('should emit values',fakeAsync(()=>{
勾号(1000);
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('div')).nativeElement.innerHTML).toBe('0');
});
但是测试失败了。从某种原因来看,角度似乎无法被观察到。我错过了什么


当我试图用
do
操作符记录可观察对象时,我在浏览器控制台中看不到任何输出。

据我所知,你不能在异步管道中使用
fakeAsync
。我希望被证明是错的,但我尝试了一段时间,没有任何结果。相反,请使用
async
utility(我将其别名为
realAsync
,以避免与
async
关键字混淆)和
wait
承诺包装
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');
  }));
});
import{async as realAsync,ComponentFixture,TestBed}来自“@angular/core/testing”;
从“./async.component”导入{AsyncComponent};
函数setTimeoutPromise(毫秒:数字):承诺{
返回新承诺((解析)=>{
setTimeout(解析,毫秒);
});
}
描述('AsyncComponent',()=>{
let组件:异步组件;
let夹具:组件夹具;
let元素:HTMLElement;
beforeach(realsync(()=>{
TestBed.configureTestingModule({
声明:[异步组件]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(异步组件);
组件=fixture.componentInstance;
元素=fixture.nativeElement;
fixture.detectChanges();
});
它('should emit values',realsync(async()=>{
等待setTimeoutPromise(1000);
fixture.detectChanges();
expect(element.getElementsByTagName('div')[0].innerHTML.toEqual('0');
}));
});

我遇到了这个问题,我很惊讶没有人找到真正的解决方案

可能的解决方案

  • 您的模板可能不会在测试中呈现,尤其是在覆盖它的情况下。因此,| async操作不会触发
  • 您使用的fixture.detectChanges()不足以允许模板呈现。呈现发生在OnInit阶段之后。因此请确保至少使用fixture.detectChanges两次
  • 可能您有
    setTimeout
    操作挂起,例如
    debounce(100)
    需要
    tick(100)
    来解决(在fakeAsync测试中)

干杯

谢谢,这真的帮了我的忙!但是fixture.detectChanges();也是工具性的。我在beforeChanges的末尾已经有了一个,就像你一样,但这还不够。你绝对可以对使用
async
管道的组件使用
fakeAsync
测试。也许你遇到的问题与需要在正确的时间刷新微任务队列有关?我使用我为m创建的助手y组件测试通常为我处理所有这些类型的细节:。