如何在Angular 4 / Jasmine中的beforeEach中等待

时间:2017-11-15 11:23:41

标签: javascript angular asynchronous jasmine

我的一个组件在ngOnInit内使用了setTimeout,例如:

ngOnInit() {
  setTimeout(() => {
      // do some setup stuff using FormBuilder
  }, 100);
}

在这个组件的单元测试中,我需要监视其中一个使用FormBuilder以编程方式构建的控件的方法之一,所以我在beforeEach中执行此操作:

describe('testing something', () => {

    beforeEach(() => {
        spyOn(component.form.controls.myControl, 'enable');
    });

    it('does something', () => {
      // test stuff
    });

}); 

在添加超时之前,测试工作正常。如何在beforeEach方法中使ngOnInit等待100毫秒超时?

我尝试将asyncfakeAsync添加到外部描述中,例如像这样:

 describe('testing something', <any>fakeAsync(() => {
     ...
 }));

describe('testing something', async(() => {
     ...
 }));

但在第一种情况下,使用fakeAsync我在测试运行器中看到一条消息错误:预计会在&#39; ProxyZone&#39;中运行,但是找不到它。,在第二种情况下,它甚至没有运行测试。我还尝试在it中包装fakeAsync方法,但这并不能延迟beforeEach

我已经尝试将spyOn方法包裹在beforeEach中的setTimeout内,但这似乎没有任何效果,即测试失败了同样的方式。

我也尝试将fakeAsyncbeforeEach一起使用,如下所示:

beforeEach(<any>fakeAsync(() => {
    tick(100);
    spyOn(component.modelForm.controls.myControl, 'enable');

  }));

但这也不起作用。它不会导致任何错误,但我想要监视的方法还没有存在,即使在勾选之后也是如此。

如何强制beforeEach等待ngOnInit()中的超时?它甚至可能吗?

2 个答案:

答案 0 :(得分:2)

如果需要,以下解决方案可以适用于beforeEach

before(() => {
  jasmine.clock().install();
})

after(() => {
  jasmine.clock().uninstall();
})

it('test case', () => {
  spyOn(component.modelForm.controls.myControl, 'enable');
  
  component.ngOnInit();

  var timeout = 2000 // 2 seconds
  jasmine.clock().tick(timeout);

  expect(component.modelForm.controls.myControl.enable).toHaveBeenCalled()
})

答案 1 :(得分:0)

我能够在done内使用Jasmine的beforeEach回调修复此问题,如下所示:

beforeEach((done) => {
    component.ngOnInit();

    setTimeout(() => {
      spyOn(component.modelForm.controls.myControl, 'enable');

      done();
    }, 100);
  });

似乎很直观!