为啥 TestBed beforeeach 使用 waitForAsync 而不仅仅是 async/await compileComponents?
Posted
技术标签:
【中文标题】为啥 TestBed beforeeach 使用 waitForAsync 而不仅仅是 async/await compileComponents?【英文标题】:Why TestBed beforeeach uses waitForAsync instead of just async/await compileComponents?为什么 TestBed beforeeach 使用 waitForAsync 而不仅仅是 async/await compileComponents? 【发布时间】:2021-03-01 21:17:42 【问题描述】:编辑:我在 Angular 上打开了一个问题,他们更新了文档:https://github.com/angular/angular/issues/39740
在 Angular 测试中,通常的做法是为 beforeEach
方法执行此操作
beforeEach(waitForAsync(() =>
TestBed
.configureTestingModule(
declarations: [BannerComponent],
)
.compileComponents(); // compile template and css
));
跟下面做有什么区别?
beforeEach(async () =>
await TestBed
.configureTestingModule(
declarations: [BannerComponent],
)
.compileComponents(); // compile template and css
);
我试图在文档中找到解释,但无法弄清楚。
https://angular.io/api/core/testing/waitForAsync#description https://v10.angular.io/guide/testing-components-scenarios#the-async-beforeeach
【问题讨论】:
【参考方案1】:关于这两种方法
我们有多种方法可以在测试角度操作时定义异步操作
使用waitForAsync()
waitForAsync
在异步测试区域中包装测试函数。当该区域内的所有异步调用都完成后,测试将自动完成。可用于包装注入调用。 来自文档
另外需要注意的是,这个方法是对初始方法async
的重命名。
async已弃用:使用
waitForAsync()
,(预计在 v12 中删除)async() 助手重命名
测试帮助函数
async
已被弃用并重命名为waitForAsync
。这个重命名背后的原因是,当我们现在有一个名为
async
的 javascript 关键字(创建 Angular 函数时该关键字不存在)时,有一个名为async()
的函数可能会令人困惑,这有点类似(您可以await
异步调用),但不同(async()
等待所有异步调用,其中async
只等待标记为 await 的调用)。归功于
Cédric Exbrayat
See this article
WaitForAsync
函数在一个特殊的异步测试区执行其主体内的代码。这会跟踪在正文中创建的所有承诺。该函数还跟踪由嵌套函数创建的任何承诺,例如,如果我们在 ngOnInit 函数中调用异步函数,这将被跟踪。
Async/ Await
基本上这使用普通的 Javascript async\ await
。我们将一个函数声明为 async 并等待一个 Promise 解决
这两种方法有什么区别?
让我们考虑一个有 5 种方法的测试asyncMethod1
,nonAsyncMethod1
,asyncMethod2
,asyncMethod3
,nonAsyncMethod2
。
使用async / await
。我们需要在下面做
beforeEach(async () =>
await asyncMethod1();
nonAsyncMethod1();
await asyncMethod2();
await asyncMethod3();
nonAsyncMethod2()
await TestBed
.configureTestingModule(
declarations: [BannerComponent],
)
.compileComponents(); // compile template and css
);
使用waitForAsync
以上将是
beforeEach(waitForAsync(() =>
asyncMethod1();
nonAsyncMethod1();
asyncMethod2();
asyncMethod3();
nonAsyncMethod2()
TestBed
.configureTestingModule(
declarations: [BannerComponent],
)
.compileComponents(); // compile template and css
));
所以通常在使用async /await
时,我们需要在使用waitForAsync
时跟踪我们所有的异步操作,这将由函数跟踪,并且一旦函数主体中的所有承诺都得到解决,承诺就会解决
【讨论】:
所以我的两个sn-ps没有区别。 两个 sn-ps 的功能完全相同,但我建议使用waitForAsync
。
好吧,这很奇怪,因为 Angular 11 CLI 使用 async/await 而不是 waitForAsync 生成一个测试文件
这里我是使用 async 作为 JS 操作,这不是 Angular 重构的 async 函数
这里只是说Angular 12为组件生成的规范文件默认使用async
/await
而不是waitForAsync
以上是关于为啥 TestBed beforeeach 使用 waitForAsync 而不仅仅是 async/await compileComponents?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在 V8Js 中运行时,Vue 路由器 beforeEach 中的错误不会抛出异常?
Angular单元测试没有通过 - 异常的phantomjs错误
Angular 7 TestBed.overrideProvider 不适用于 ActivateRoute