【问题标题】:What is the difference between angular testing async+whenStable and fakeAsync+tick?角度测试 async+whenStable 和 fakeAsync+tick 有什么区别?
【发布时间】:2019-04-25 21:46:58
【问题描述】:

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

我很难理解的是是否真的存在执行顺序差异 - 因为如果没有,为什么要同时提供?

这让我了解了 JS 宏任务和微任务,我想知道这两种方法是否不同?

【问题讨论】:

标签: angular testing


【解决方案1】:

这是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 测试区 中执行其主体内的代码。这会拦截并跟踪在其主体中创建的所有 Promise。

只有当所有这些待处理的 Promise 都已解决时,它才会解决从 whenStable 返回的 Promise。

您可以使用它来避免使用 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 函数在一个特殊的fakeasync 测试区 中执行其主体内的代码。这会拦截并跟踪在其主体中创建的所有 Promise。

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

因此,当我们调用 tick() 时,应用程序会坐下来等待 Promise 得到解决,然后让执行移至下一行。

使用它的主要优点是它使代码更线性,就好像我们在执行同步代码一样,没有回调来混淆大脑,一切都更容易理解。

结论:

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

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

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

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

这些点会让你想,如果很难阅读,为什么要使用async + whenStable。为什么不直接使用fakeAsync + tick 呢?原因之一是:

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

您可以在GitHub Thread 上阅读更多相关信息。

【讨论】:

  • 我从中了解到的是,它们完全相同,但语法更好,这引出了一个问题,为什么选择使用更差的语法?你也可以在 fakeAsync 区域内做 fixture.whenStable 但我不知道这是否有效?
  • 让我尝试通过更新答案来回答这个问题。
  • @Craig,我已经更新了答案。希望现在更清楚了。
  • 你太棒了。
  • @SiddAjmera 超级好答案。只是想知道为什么在第一个示例中不使用标准 async/await 而不是 Promise.then?我相信这两种方法几乎没有区别。
猜你喜欢
  • 1970-01-01
  • 2018-04-01
  • 2017-08-15
  • 2019-10-23
  • 2019-07-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 2020-08-27
相关资源
最近更新 更多