關於 fireEvent 的考量
互動 vs. 事件
基於引導原則,您的測試應盡可能模擬使用者與您的程式碼(元件、頁面等)的互動方式。考慮到這一點,您應該知道 fireEvent
並非完全是使用者與您的應用程式互動的方式,但在大多數情況下都已足夠接近。
考慮 fireEvent.click
,它會建立一個 click 事件並在給定的 DOM 節點上分派該事件。當您只想測試點擊元素時會發生什麼時,這在大多數情況下都運作正常,但是當使用者實際點擊您的元素時,通常會觸發以下事件(按順序)
- fireEvent.mouseOver(element)
- fireEvent.mouseMove(element)
- fireEvent.mouseDown(element)
- element.focus()(如果該元素可聚焦)
- fireEvent.mouseUp(element)
- fireEvent.click(element)
然後,如果該元素剛好是 label
的子元素,那麼它也會將焦點移至該 label 所標記的表單控制項。因此,即使您真正想要測試的只是點擊處理程序,單單使用 fireEvent.click
就會遺漏使用者沿途觸發的其他幾個潛在的重要事件。
同樣,大多數情況下,這對於您的測試來說並非至關重要,而簡單使用 fireEvent.click
的取捨是值得的。
替代方案
我們將描述對您的測試進行的幾個簡單調整,這些調整將提高您對元件互動行為的信心。對於其他互動,您可能需要考慮使用 user-event
或在真實環境中測試您的元件(例如,手動、使用 cypress 自動測試等)。
Keydown
keydown 會在目前已聚焦的元素、body 元素或 document 元素上分派。在此之後,您應該優先考慮
- fireEvent.keyDown(getByText('click me'));
+ getByText('click me').focus();
+ fireEvent.keyDown(document.activeElement || document.body);
這也將測試有問題的元素是否可以接收鍵盤事件。
Focus/Blur
如果元素聚焦,則會分派 focus 事件,文件中活動的元素會變更,並且先前聚焦的元素會失焦。若要模擬此行為,您可以簡單地使用強制 focus 取代 fireEvent
- fireEvent.focus(getByText('focus me'));
+ getByText('focus me').focus();
此方法的一個好處是,如果元素無法聚焦,則任何對已觸發 focus 事件的斷言都會失敗。如果您接著執行 keydown 事件,這尤其重要。