![](/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.