角度测试async + whenStable和fakeAsync + tick有什么区别?

时间:2018-11-23 09:36:03

标签: angular testing

我了解asyncfakeAsync方法会设置某种侦听器,该侦听器记录所有异步操作,以便角度测试框架可以使用whenStabletick()进行管理等待所有这些东西完成。我认为那是正确的吗?

我要努力理解的是,实际上是否存在执行顺序上的差异-因为如果没有,为什么要同时提供两者?

这使我学习了JS宏任务和Micro任务,我想知道这两种方法是否在这一领域有所不同?

1 个答案:

答案 0 :(得分:5)

这是 Testing Asynchronous Code - CodeCraft

的摘要

async + whenStable

考虑以下这段代码:

it('Button label via async() and whenStable()', async(() => { 
  fixture.detectChanges();
  expect(el.nativeElement.textContent.trim()).toBe('Login');
  spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
  fixture.whenStable().then(() => { 
    fixture.detectChanges();
    expect(el.nativeElement.textContent.trim()).toBe('Logout');
  });
  component.ngOnInit();
}));

async函数在特殊的 async测试区域中执行其体内的代码。这样可以拦截并跟踪其体内创建的所有承诺。

仅当所有这些未完成的承诺都得到解决后,它才会解析从whenStable返回的承诺。

您可以使用它来避免使用Jasmine的间谍机制来检测何时解决了诺言。

此机制比使用普通的Jasmine解决方案略胜一筹,但是还有另一个版本可以为我们提供细粒度的控制,还可以让我们将测试代码布置为同步的。


fakeAsync + tick

现在考虑这段代码:

it('Button label via fakeAsync() and tick()', fakeAsync(() => { 
  expect(el.nativeElement.textContent.trim()).toBe('');
  fixture.detectChanges();
  expect(el.nativeElement.textContent.trim()).toBe('Login');
  spyOn(authService, 'isAuthenticated').and.returnValue(Promise.resolve(true));
  component.ngOnInit();

  tick(); 
  fixture.detectChanges();
  expect(el.nativeElement.textContent.trim()).toBe('Logout');
}));

async一样,fakeAsync函数在特殊的 伪造 async测试区域中执行其体内的代码。这样可以拦截并跟踪其体内创建的所有承诺。

tick()函数阻止执行并模拟时间的流逝,直到所有未完成的异步活动完成。

因此,当我们调用tick()时,应用程序将坐下并等待承诺被解决,然后让执行移至下一行。

使用此方法的主要优点是,它使代码更加线性,就像我们正在执行同步代码一样,没有回调方法使思维混乱,并且所有内容都更易于理解。

结论:

我们可以使用三种机制来测试异步代码:

  1. 茉莉花的done函数和间谍回调。这行得通,但希望我们了解应用程序中的所有承诺,并能够将它们挂钩。

  2. 我们可以使用Angular asyncwhenStable函数,我们不需要自己跟踪promise,但是我们仍然需要通过回调函数布置代码,这可能很难阅读。

  3. 我们可以使用Angular fakeAsynctick函数,这还使我们可以将async测试代码布置为同步的。

这些要点使您认为,如果难以阅读,为什么要使用async + whenStable。为什么不简单地使用fakeAsync + tick呢?嗯,原因之一可能是因为:

  

重要   fakeAsync确实有一些缺点,例如doesn’t track XHR requests

您可以在此GitHub Thread上了解有关此内容的更多信息。