角度测试异步管道不会触发可观察对象

时间:2017-06-29 09:36:50

标签: javascript angular testing

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

@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时,我在浏览器控制台中看不到任何输出。

3 个答案:

答案 0 :(得分:0)

您可以尝试以下操作:

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();
  });
});

每当观察到新元素被观察时,您可以订阅它并检查价值和模板是否符合您的期望。

答案 1 :(得分:0)

据我所知,您不能在异步管道中使用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');
  }));
});

答案 2 :(得分:0)

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

可能的解决方案

  • 您的模板可能不会在测试中呈现,特别是如果您覆盖它。因此,异步操作不会触发。
  • 您使用的import os import shutil root_src_dir = r'C:/test' #Path of the source directory root_dst_dir = 'c:/test.copy' #Path to the destination directory for root, _, files in os.walk(root_src_dir): for file in files: if file.startswith("4") and len(file) == 7: shutil.copy(os.path.join(root, file), root_dst_dir) 不够多,无法进行模板渲染。渲染发生在OnInit阶段之后。因此,请确保至少使用两次fix.detectChanges。
  • 也许您有len(file) == 7待处理的操作,例如len(os.path.splitext(file)[0]) == 7将需要fixture.detectChanges()来解决(在fakeAsync测试中)。

欢呼