跳至主要內容

關於 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 事件,這尤其重要。