![](/img/trans.png)
[英]How to wait for findOneAndUpdate to finish before continuing async.series
[英]How to wait for async mounted of Vue component to finish before continuing with testing
我有一个带有异步生命周期钩子方法的Vue2
组件:
// create report when component is loading
async mounted(): Promise<void> {
await this.createReport();
}
现在我想通过jest
和vue/test-utils
测试我的组件,但测试应该await
组件的mounted()
方法完成。
const wrapper = await mount(MyComponent, { // <-- no Promise, await has no effect
localVue
});
await flushPromises(); // <-- is not waiting for the async mounted()
expect(wrapper.vm.currentReport.sections).toHaveLength(5); // <-- failing since createReport not finished
不幸的是mount()
或shallowMount()
不会返回一个Promise
并且不会等待生命周期钩子的完成。
到目前为止,唯一的选择是await flushPromises()
,它对挂载的方法没有影响。 其他人写了await mount()
但由于没有返回 Promise,这也没有效果。 我认为大多数测试都通过了,因为它们足够快,所以安装已经完成。 这对我来说不是这样,因为我们正在加载一些正确的数据,这需要几秒钟。
用户将看到加载屏幕并耐心等待与组件交互,不幸的是不会等待。
在挂载逻辑完成后,如何用 jest 开始我的 Vue 测试?
如果您将mounted
标记为async
,则在promise resolve/rejected 1之前,您不会阻止组件安装。 它将挂载,并在稍后的某个时间点, mounted
将解析/拒绝。
如果您想等到某事发生(例如: this.createReport()
解决),在您的mounted
内,在await
之后,将布尔值设置为true
(例如: this.hasReport
)。
现在,您可以watch
该反应数据值并触发其他一些功能,或者您可以在<template>
中使用它来防止某些 DOM 在它拥有必要的数据之前呈现。
测试异步行为的典型方法是实际模拟异步响应。 您尚未向我们展示createReport()
的作用,但它可能在组件逻辑之外。 对于单元测试,它做什么并不重要。 您应该模拟所有要测试的案例(解决成功,拒绝失败,...)。
为什么要嘲讽? 因为,例如,如果在运行测试时 Internet 不工作,您不希望测试失败。 因此,您不应该向某个遥远的 API 发出实际的 http 请求。 您应该用一个函数(模拟)替换该调用,返回一个用预期数据解析的承诺。 或以预期的错误拒绝。
所有测试框架( jest
、 vitest
等)都让 mocking 变得轻而易举。
请参阅测试异步行为。
1 - 从技术上讲,这个陈述在 Vue 2 中只有 100% 正确。Vue 3 有一个内置的实验性<Suspense>组件,它有两个插槽:内容和后备。 如果内容槽内的任何组件,无论多深,都具有异步created
和/或mounted
的钩子, <Suspense>
组件将呈现回退槽内容,直到所有内容承诺解决或拒绝。 当它们都具有时,它将显示内容槽。
这与您的情况无关,因为您使用的是 Vue 2,但我必须指定它以避免对 Vue 3 用户造成混淆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.