繁体   English   中英

如何在继续测试之前等待 Vue 组件的异步安装完成

[英]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();
}

现在我想通过jestvue/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 请求。 您应该用一个函数(模拟)替换该调用,返回一个用预期数据解析的承诺。 或以预期的错误拒绝。

所有测试框架( jestvitest等)都让 mocking 变得轻而易举。

请参阅测试异步行为


1 - 从技术上讲,这个陈述在 Vue 2 中只有 100% 正确。Vue 3 有一个内置的实验性<Suspense>组件,它有两个插槽:内容和后备。 如果内容槽内的任何组件,无论多深,都具有异步created和/或mounted的钩子, <Suspense>组件将呈现回退槽内容,直到所有内容承诺解决或拒绝。 当它们都具有时,它将显示内容槽。
这与您的情况无关,因为您使用的是 Vue 2,但我必须指定它以避免对 Vue 3 用户造成混淆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM