編寫單元測試有助於改善**的質量,在編寫單元測試時,某些功能可能依賴了其他**(比如呼叫了其他元件)。
通常我們只想測試這些功能本身,而不想測試它所依賴的**。
為什麼呢?
單元測試的目標是驗證該功能是否正確,然而功能所依賴的**是處於功能範圍外的,這些**可能是一些外部的元件,單元測試無法驗證這些外部元件的準確性。
單元測試因呼叫「依賴的**」出錯而失敗時,會影響測試結果的判斷,我們無法確定功能本身是否是正確的。
也許功能是正確的,但呼叫依賴的**出錯時,這個單元測試仍然會被認為是失敗的。
如果要測試這些被依賴的**,我們應該另外地為這些**編寫單元測試。
如何解決?
「依賴的**」成了我們編寫這類單元測試的攔路石,我們可以通過2種方式來解決這個問題:
1. mock依賴的**
2. 分解依賴
mock的強大是毋庸置疑的,然而mock不是萬能的,它也是有限制的,我們不能在單元測試中mock靜態類。
但是,通過「分解依賴」可以解決這個問題,本文將通過乙個示例來演示這2種方式。
這段**描述了乙個場景——「飼養動物」,它包含2個類:
animalfeedingservice(動物飼養服務),以及靜態類feeder(飼養員)。
animalfeedingservice描述了「飼養」行為,feeder類描述了「補充食物」行為。
在飼養動物時,如果動物的食盆是空的,則飼養員需要補充食物。
/// /// 動物飼養服務單元測試**(基於xunit和rhino.mocks框架)///
public class animalfeedingservice
public void feed()
}/// /// 飼養員
///
public static class feeder
}
public class animalfeedingservicetests由於feeder是乙個靜態類,所以在為animalfeedingservice編寫單元測試時,我們無法mock feeder類,而且feeder類的功能我們也不想在這個單元測試中驗證。}
如果在呼叫feeder.replenishfood()時就出錯了,這個單元測試的執行就是失敗的。
同時,feed()方法的正確性也無法驗證。
為了能在單元測試中解除對feeder類的依賴,我們可以為feeder類新增包裝介面ifeederservice,然後讓animalfeedingservice依賴於這個包裝介面。這樣在animalfeedingservicetest類中,我們就不需要考慮feeder類了。
/// /// 動物飼養服務單元測試**(基於xunit和rhino.mocks框架)///
public class animalfeedingservice
public ifeederservice feederservice
public animalfeedingservice(ifeederservice feederservice)
public void feed()
}/// /// 飼養服務介面
///
public inte***ce ifeederservice
/// /// 飼養服務實現
///
public class feederservice : ifeederservice
}/// /// 飼養員
///
public static class feeder
}
public class animalfeedingservicetests重構後的animalfeedingservicetests,由於ifeederservice是mock的,所以ifeederservice的replenishfood()方法根本不會被呼叫,因此feeder的replenishfood()方法也不會被呼叫。}
呼叫feed()方法時,feeder.replenishfood()方法被忽略了,這可以讓我們更加關注於feed()方法本身的邏輯。
小酌重構系列目錄彙總
關注keepfool
小酌重構系列 12 去除上帝類
神說 要有光 就有了光。聖經 上帝要是會寫程式,他寫的類一定是 上帝類 程式設計師不是上帝,不要妄想成為上帝,但程式設計師可以寫出 上帝類 上帝是唯一的,上帝的光芒照耀人間,上帝是很愛面子的,他知道程式設計師寫了 上帝類 搶了他的風頭,於是他降下神罰要懲戒程式設計師。既然你寫了 上帝類 那麼就將你流...
小酌重構系列 17 提取工廠類
在程式中建立物件,並設定物件的屬性,是我們長幹的事兒。當建立物件需要大量的重複 時,看起來就不那麼優雅了。從類的職責角度出發,業務類既要實現一定的邏輯,還要負責物件的建立,業務類幹的事兒也忒多了點。物件建立也是 一件事 我們可以將 這件事 從業務 中提取出來,讓專門的類去做 這件事 這個專門的類一般...
小酌重構系列 21 避免雙重否定
在自然語言中,雙重否定表示肯定。但是在程式中,雙重否定會降低 的可讀性,使程式不易理解,容易產生錯覺。人通常是用 正向思維 去理解一件事情的,使用雙重否定的判斷,需要開發者以 逆向思維 的方式去理解它的含義。另外,在寫程式時,符號很容易被疏忽和遺漏,一不小心則會編寫出錯誤的 從而產生bug。所以,在...