單元測試法則
單元測試法則
What should we test?
Incoming & Outgoing Messages
上圖表示一個物件是如何被測試的。
測試物件的時候,你可以發現受測物件會
接收
與發送
訊息:- Incoming Messages 表示呼叫受測物件的訊息
- Outgoing Messages 表示受測物件
傳遞
給其依賴物件的訊息
訊息可以被傳進物件,也會被物件傳遞出去(如上圖你可以看見有訊息進入物件,也有訊息從物件出去)。
進行測試時,你只能對物件傳遞訊息,沒有辦法看見物件的內部。這就是為什麼要
測試介面,不要測試實作。 (testing the interface, and NOT the implementation.)
測試介面讓我們可以隨意切換實作類別,並且不破壞測試程式。
Query & Command Messages
除了 Incoming & Outgoing Messages 以外,訊息還分為 Query 與 Command 兩種:
Query Message: messages return data without changing anything.
只返回 Data,不做修改任何物件屬性的訊息 - 不會替應用程式帶來副作用。
Command Message: messages modify data without returning any data.
只修改物件屬性,但不返回任何 Data 訊息 - 一定會有副作用。
合併的 Command 與 Query 訊息:
這種訊息除了修改資料與回傳資料外,還可能有隱藏的副作用。
(如新增一筆 user 資料並返回新的 user ID,但是 DB 內的 ID 自動 +1)
在商業邏輯一定要使用合併訊息時,一定要確保這些訊息不能含有意料外的副作用。
Test Double
為什麼要 Test Double?
1. 隔離依賴:
單元測試目的是要測試受測物件的行為是否符合預期,如果連受測物件的依賴物件也一起進行測試,那就叫做
整合測試了。
因此單元測試需要隔離依賴。
2. 要求快速:
單元測試的時間應該非常短,才可以
進行重構時,一點點修改就要立刻執行測試,確保功能沒有被改壞。如果每次執行測試,受測物件將訊息遞給依賴物件處理 15 秒才回傳值。就會大幅減緩開發速度。
向開發者快速反饋信息。進行重構時,一點點修改就要立刻執行測試,確保功能沒有被改壞。如果每次執行測試,受測物件將訊息遞給依賴物件處理 15 秒才回傳值。就會大幅減緩開發速度。
使用測試替身隔離依賴物件,避免訊息在 N 多個物件之間來回傳遞。(參考上圖)即可加快單元測試的速度。
測試替身用途
Stub 用來測試 Outgoing Query Message
Mock 用來測試 Outgoing Command MessageStub 代替的訊息不會對整個應用程式帶來副作用,所以訊息如何被傳遞並不那麼重要。
Mock 代替的訊息會對應用程式有副作用。所以一定要用 Mock 確保受測程式有沒有正確將訊息傳遞出去。
參考資源
留言
張貼留言