🎯 什麼情境該想到我

當你「在 C/C++ 裡想把某個類別成員函式在測試時整個換掉,而它的宣告和定義是分開的」的時候。

⚙️ 怎麼用(步驟)

原理(p.266):「有些語言允許你在一個地方宣告型別然後在另一個地方定義它。這一點體現得最明顯的就是在 C/C++ 中。在 C/C++ 中我們可以在一處地方宣告一個函式/方法,然後在另一處地方(通常是實作檔案中)定義它。這一能力可以用來幫助我們解依賴。」

做法(p.267):在測試檔案中包含目標類別的標頭檔,然後在測試檔案裡給目標方法提供另一個定義。「只需在測試中直接定義有關方法,我們便可以提供只用於測試的方法定義。我們可以給那些我們在測試時並不關心的方法定義一個空的方法體,也可以定義可用於所有測試的感知方法。」

步驟(p.268,書中標明「在 C++ 中使用定義補全技術的步驟」)

  1. 找出你想要對其成員函式實施定義替換的類別。
  2. 確認該類別的成員函式定義是在源檔案而非標頭檔中。
  3. 將該標頭檔包含到待測試類別的測試源檔案中。
  4. 確保該類別的源檔案並不參與建置。
  5. 建置,找出沒替換定義的成員函式。
  6. 往測試源檔案中添加相應的成員函式定義,直到建置成功。

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

書中對這條技術的保留意見是全章最重的,原文(p.267–268):

  • 必須拆出獨立的測試執行檔:「在 C/C++ 中使用定義補全技術,這就意味著我們得為使用了定義補全的測試建立單獨的可執行檔了。因為如果不這麼做的話,替換的定義就會跟原有的定義在連接期產生衝突。」
  • 同一個方法會有兩組定義:「一組位於測試源檔案中,另一組位於產品程式碼源檔案中。這可能會給程式碼維護帶來很大負擔。」
  • 可能害你 debug 到錯的東西:「如果你的除錯環境沒有設置妥當的話,甚至可能會使除錯器載入了錯誤的除錯資料。」
  • 作者明講不推薦:「因此,並不推薦使用該技術,除非你遇上了最糟糕的依賴情況。而且即使如此,我也建議你只把該技術用在解開初始依賴上。一旦解除了初始依賴,你應該就能快速地將類別置入測試之下,這時重複的定義便可以刪除了。」(p.267–268)
  • 語言限定:這條技術依賴「宣告與定義分離」的語言能力,書中的說明與步驟都是針對 C/C++ 的。
  • 整章共通的誠實取捨:「這些技術並不能立竿見影地讓設計變得更好。」(p.258)它們是要在沒有測試的情況下使用的,目的是「將測試安置到位」。

🔗 相關工具