非同步方法
提供數個工具來處理非同步程式碼。這些工具可用於等待元素因應事件、使用者動作、逾時或 Promise 而出現或消失。(請參閱測試消失的指南。)
非同步方法會回傳 Promise,因此在呼叫時務必使用 await
或 .then
。
findBy
查詢
findBy
方法是 getBy
查詢和waitFor
的組合。它們接受 waitFor 選項作為最後一個引數 (例如 await screen.findByText('text', queryOptions, waitForOptions)
)。
當您預期元素出現,但 DOM 的變更可能不會立即發生時,可以使用 findBy
查詢。
const button = screen.getByRole('button', {name: 'Click Me'})
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')
waitFor
function waitFor<T>(
callback: () => T | Promise<T>,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<T>
當您需要等待任何時間時,可以使用 waitFor
,等待您的期望通過。回傳 *偽值條件不足以*觸發重試,回呼必須擲回錯誤才能重試條件。以下是一個簡單的範例
// ...
// Wait until the callback does not throw an error. In this case, that means
// it'll wait until the mock function has been called once.
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
// ...
waitFor
可能會執行回呼多次,直到達到逾時時間。請注意,呼叫的次數會受到 timeout
和 interval
選項的限制。
如果您有一個單元測試會模擬 API 呼叫,而且您需要等待所有模擬的 Promise 都解析時,這會很有用。
如果您在 waitFor
回呼中回傳 promise (明確地或使用 async
語法隱含地),則 waitFor
公用程式不會再次呼叫您的回呼,直到該 promise 拒絕。這可讓您 waitFor
必須非同步檢查的事項。
預設的 container
是全域 document
。請確定您等待的元素是 container
的後代。
預設的 interval
是 50ms
。不過,它會在啟動間隔之前立即執行您的回呼。
預設的 timeout
是 1000ms
。
預設的 onTimeout
會接收錯誤,並將 container
的列印狀態附加至錯誤訊息,這應該有助於追蹤導致逾時的原因。
預設的 mutationObserverOptions
是 {subtree: true, childList: true, attributes: true, characterData: true}
,這會偵測 container
及其任何後代中子元素的加入和移除 (包括文字節點)。它也會偵測屬性變更。當任何這些變更發生時,它會重新執行回呼。
waitForElementToBeRemoved
function waitForElementToBeRemoved<T>(
callback: (() => T) | T,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<void>
若要等待從 DOM 中移除元素,您可以使用 waitForElementToBeRemoved
。waitForElementToBeRemoved
函式是 waitFor
公用程式的小包裝函式。
第一個引數必須是元素、元素陣列或回傳元素或元素陣列的回呼。
以下範例說明由於元素已移除,因此 Promise 已解析
const el = document.querySelector('div.getOuttaHere')
waitForElementToBeRemoved(document.querySelector('div.getOuttaHere')).then(() =>
console.log('Element no longer in DOM'),
)
el.setAttribute('data-neat', true)
// other mutations are ignored...
el.parentElement.removeChild(el)
// logs 'Element no longer in DOM'
如果第一個引數為 null
或空陣列,則 waitForElementToBeRemoved
會擲回錯誤
waitForElementToBeRemoved(null).catch(err => console.log(err))
waitForElementToBeRemoved(queryByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(queryAllByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(() => getByText(/not here/i)).catch(err =>
console.log(err),
)
// Error: The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.
選項物件會轉送到 waitFor
。