簡體   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