前面有稍微練習一下如何進行Unit Test。我們用NUnit Test來進行簡單的測試,其中包含了檢查對象的返回值測試以及系統狀態測試。然而實際上往往會更為複雜,有時候測試的對象會依賴另一個我們無法控制的對象(可能是系統時間、別的程式給的值等等),這個時候測試會變得非常難以掌控。
當測試的時候越簡單越好,因這樣才能鎖定問題發生的位置與原因。試想如果把很多方法全部包在一起,或是把很多外部變數放在我們的測試方法內,當這個測試項目發生錯誤的時候,我們很難快速的的鎖定原因在哪裡。為了減少對外部的依賴性,所以產生出三個播除依賴的方法,也就是三種模擬對象的方式:stub
、mock
、fake
。
Stub(存根)
當需要從外部取得資料,但是卻又不想直接從外部取得,因為這樣會依賴外面的功能時,我們可以製作一些「虛假的資料」,這種作法就是「stub」。其實根我們前幾天練習的就是屬於這個部分,我們並沒有真的取得一個檔案,而是「假裝」有這個檔名。
例如:我們想要從資料庫取得客戶資料,但由於是在測試,我們並不想要真的從資料庫取得,所以我們就製造了一些假資料來提供測試。讓我們可以專心在功能上,而不用費心連線至資料庫,還要檢查資料庫是否連線正常。
Mock(模擬對象)
這個作法很類似stub(網路上也有許多爭議以及分析文章),這邊就以本書為主。
Mock是指系統中的偽造對象。提供目標對象進行測試。也就是說stub是測試某個功能,但是mock卻是模擬對象,卻會被測試。換言之,stub只有true
或是false
,不會發生失敗,但是mock,卻會發生失敗。
斷言對象:
所以主要的對象通常是void
,也就是沒有回傳值和改變系統狀態。例如要檢查「記錄log」、「寄信功能」,不但沒有回傳值,也沒有系統狀態的改變,只有void
的功能。可以說mock時常常比stub還要更複雜。
Fake(假對象)
而fake則是把外在的環境,縮小模擬成一個object,等同於模擬出一個較為完整的測試環境,也就是模擬出外在環境以及各式功能,有時會掉用到外部資料
簡單來說,就是範圍不太一樣,stub主要是用在程式參數變化,mock則是當要測試非回傳值或系統狀態修改時使用。fake當要進行較大規模的時候進行測試,可以減少更多的相依性。
接下來幾天,將會討論這幾個假物件功能,用於隔離或是更容易的進行Unit Test