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

Cra*_*aig 4 testing angular

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

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

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

Sid*_*era 7

这是测试异步代码的摘要-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();
}));
Run Code Online (Sandbox Code Playgroud)

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');
}));
Run Code Online (Sandbox Code Playgroud)

就像asyncfakeAsync函数在一个特殊的伪造 async测试区中在其体内执行代码。这会截取并跟踪其体内创建的所有承诺。

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

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

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

结论:

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

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

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

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

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

Important fakeAsync确实有一些缺点,例如,它不跟踪XHR请求

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