React Unit Test | 測試 Component 時什麼才是最重要的?

神Q超人
Enjoy life enjoy coding
5 min readNov 19, 2019
Photo by Burst on Unsplash

前言

Hi!大家好,我是神 Q 超人,最近似乎更的有點頻繁,可能是把之前因為忙碌而沒時間打的份通通打回來 😂,本篇要和大家分享的內容源自於 這個問題,問題內容主要是

「當使用 react-testing-library 測試 component 的時候,該怎麼取得或確認 state 的值呢?」(註一)

雖然作者是以 react-testing-library 這個測試框架的角度發問,但下方回應的內容對 Component 的測試來說還滿有價值的,不論大家現在的答案是什麼,不如先一起看看吧!看完後,說不定會深深影響到各位對 Component 的測試方式(就我而言第一次看到還滿有收穫的 😂)。

面對這個問題,在 1F 的 Tony Davis 先表示:「很遺憾,react-testing-library 的設計不建議這樣做!」接著繼續提出 react-testing-library 官方 指導原則 裡的其中一點:

只要是有關 render 的 component,都不鼓勵處理 component 的 instance,因為比起 component 的 instance,更重要的是 DOM 節點。

下一段解釋說,如果 Component 最後產生的結果是 DOM,你就應該要斷言它,因為那是使用者實際會看到的內容。

直接斷言 State 容易造成「無效測試(註二)」,即使 State 的值都如你預期的變化,但只要 Render 內的邏輯有問題,最終呈現在使用者面前的 UI 仍然會是錯的。第一回合先到這裡結束。

而發問者在第二回合的開始又翻開覆蓋的魔法卡「所以也不建議對 Component 中的處理程序(event handler)用 jest.spyOn (Mock 的一種)做斷言囉?」

Tony Davis 針對這個問題回答說:「沒錯!你可以思考一下,使用者會在乎你的方法有沒有正確被執行嗎?或是當你的方法被執行後的任何一切流程是否正確?」

不會!他們只在乎畫面有沒有正常變動!(註三)

接著又對 jest.spyOn 提出一些看法,他說:「某些情況下,你也許會想要用 jest.spyOn,但我搜索到的情況大都被用來斷言獲取資料的請求(Fetchaxios 等等)。」

之後 Tony Davis 召喚了 react-testing-library 的開發者 Kent C. Dodds,想問問他的想法,Kent C. Dodds 先將 Component 的需求定義了兩個面向:

  1. 末端使用者:會重視畫面的交互作用(例如點了某個按鈕)
  2. 開發者:會想知道 Component 在使用時需要哪些 Props(Callback 事件)

所以 react-testing-library 盡可能地想讓你能夠以最接近使用者的操作,與 Component Render 出來的 DOM 做互動。對於開發者,你也可以用最正確的方式證實需要傳入哪些 Props 給 Component,這時候的 Callback Props 就可以用 Mock 做斷言,例如:

改編討論串中的例子

最後提問者 Joel Pablo (第一次提到他名字)用自問自答的方式整理了他所學習到的事情:「但是如果我想為 Component 的內部方法做測試該怎麼辦呢?還是說我們在做測試的時候,重點應該放在如何正確使用 Component,而不是 Component 內部的方法?」

這個想法顯然是正確的,Kent C. Dodds 回覆:「沒錯!不論是使用者或是開發者都不會在乎關於內部方法的事情,他們只在乎傳入的 Props 與 Render 出來的畫面是否正確。」

這就是你測試 Component 時,與 Component 做互動的訣竅!不需要去管內部如何使用,只要在乎 UI 能夠正確,並能操作它執行我們傳入的 Props!

備註專區

註一:問題的原文是「How do you check or get component state value?」,雖然沒有提到是使用 react-testing-library,但是下方的回答明確的指出 RTL(react-testing-library),所以我就直接加上去,讓閱讀起來可以順暢一些。

註二:原文是「false positives」,意思是「呈現虛假的結果」,既然測試呈現了虛假的結果就代表會導致「無效測試」,因此就直接放無效測試。

註三:原文裡沒有這一句,但這應該是他希望發問者根據上文的疑問得出來的結果,就直接補上了。

其實一開始我學習用 Enzyme 練習做單元測試的時候,觀念還沒有那麼清楚,雖然沒有到把 Component 中的 Method 取出來測試的地步(因為我也還不會),但都矇懞懂懂的斷言 Component 內部的 State 是否正確,像是 這篇文章 內的幾個例子,現在看起來真的非常不 OK。

一直到使用了 testing-react-library,從它的使用方法開始就一整個讓人疑惑,於是「為什麼會這樣做?」的想法就驅使我開始去了解有關它的一切!而幸運的是創作者 Kent C. Dodds 是個非常樂於分享的人,本身除了在經營 Blog 外也有 Youtube 頻道,私心非常推薦可以看一下它如何看待 Component!真的可以學到非常多知識!

參考資料:

  1. https://spectrum.chat/testing-library/help/how-do-you-check-or-get-component-state-value~183ce3e8-5aa4-4f2d-b79e-cba797128964
  2. https://github.com/testing-library/react-testing-library#guiding-principles

--

--