加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
利用VS2010平台做單元測試(3)--
進階單元測試實務(下)
文‧圖/陸雲中 2011/7/14 上午 11:54:19

接續上篇,Typemock Isolator是一套基於Visual Studio 2010的Mock Library,它完全與Visual Studio 2010內建的unit test framework相容。Typemock Isolator有以下特色:
●可以Mock 任何 .Net類別、介面、建構式等
●與Visual Studio 2010完全整合
●支援.Net Framework 2.0, 3.0, 3.5, 4.0版
●支援C#與VB.net
●支援Visual Studio程式碼覆蓋率

其他特色請參考官方網站。首先,請先安裝Typemock Isolator試用版,因為Typemock Isolator與Visual Studio 2010完全整合,所以Typemock Isolator可以在測試專案中使用,使用的方法為在測試專案中參考Typemock Isolator C# APIs與 Typemock Isolator core DLL組件,如圖1所示。


▲ 圖1:參考Typemock Isolator相關組件

將前述提到的測試專案依圖1加入參考相關組件,完畢後測試專案的「參考」如圖2所示。


▲ 圖2:測試專案參考Typemock Isolator相關組件

接下來就可以開始撰寫使用Typemock Isolator的單元測試。先在DemoUnitTest專案下新增類別檔案,名稱為SecurityLogServer.cs,並且新增類別SecurityLogServer,如範例程式碼1所示。


▲ 程式碼1

然後在BankAccount.cs的BankAccount類別加上新方法Credit4,如範例程式碼2所示。


▲ 程式碼2

主要是加上了當帳戶提款金額為負數時,呼叫mySecurityLogServer.Send()方法通知遠端伺服器提款金額為負數。

然後,對credit4()方法建立單元測試,目前假設的測試案例是,當帳戶提款金額為負數時,若mySecurityLogServer.Send()錯誤時(例如:網路問題),是否會拋出Exception("amount and Log Server down.")異常。這種測試案例只能在mySecurityLogServer.Send()發生錯誤時才能測試,並不容易被觸發,使用Mock是較好的選擇。

接下來筆者使用Typemock Isolator Mock mySecurityLogServer.Send()方法,並且改變mySecurityLogServer.Send()方法的行為。首先,打開BankAccountTest.cs,增加Typemock Isolator引用,例如:「using TypeMock.ArrangeActAssert」。

然後修改credit4Test()方法如範例程式碼3所示。


▲ 程式碼3

首先,所有需要使用Typemock Isolator的測試類別方法都必須要加上[Isolated]屬性,如下面程式碼片段所示:



接著說明使用Typemock Isolator的單元測試撰寫方式,簡稱為AAA。第一個A指的是Arrange,第二個A指的是Act,第三個A指的是Action:
●Arrange:在執行測試前先定義Typemock Isolator應該如何Mock相關的類別。
●Act:呼叫受測類別。
●Assert:驗證呼叫結果是否符合預期。

依照目前設定的單元測試案例邏輯,受測類別方法Credit4()在提款金額amount小於0時會呼叫SecurityLogServer.Send方法,因為本測試案例要測的是呼叫SecurityLogServer.Send方法失敗時,Credit4是否能夠拋出Exception("amount and Log Server down.")異常。

所以使用Typemock Isolator「製造」一個Mock類別,然後在呼叫credit4時由Typemock Isolator將原有的SecurityLogServer替換掉。如範例程式碼4所示。


▲ 程式碼4

替換掉之後,就可以開始定義fakeSecurityLogServer這個Mock類別的行為了。可以將fakeSecurityLogServer.Send方法改為直接拋出異常Exception("amount and Log Server down.")。如範例程式碼5所示。


▲ 程式碼5

因為fakeSecurityLogServer是Mock類別,所以原本SecurityLogServer.Send的程式碼並不會執行,而是會直接拋出Exception("amount and Log Server down.")異常。

綜合範例程式碼4與5代表的意義是:Typemock Isolator會在單元測試Credit4Test呼叫Credit4時,如果Credit4有利用new關鍵字產生DemoUnitTest.SecurityLogServer類別物件,會被Typemock Isolator替換成Mock類別物件,名稱為fakeSecurityLogServer。

當fakeSecurityLogServer.Send被呼叫時,Typemock Isolator會直接拋出異常Exception("amount and Log Server down.")。如此,單元測試Credit4Test的Arrange階段完成了。

接下來就可以實例化Bank類別物件,物件名稱為target,然後呼叫target.credit4,傳入負數的提款金額,Tpyemock Isolator會依照剛才在Arrange定義的Mock行為替換類別物件並直接拋出異常。這個直接呼叫測試類別方法的階段就是Act。

呼叫完畢後,需要驗證呼叫結果是否符合預期,也就是Aseert階段。在這個測試案例中,只要確認異常Exception("amount and Log Server down.")有被Credit4()拋出,即可確認單元測試結果正確。

以上就是使用Typemock Isolator以AAA方式進行單元測試的簡單例子。這例子說明有了好的Mock Libary,可以撰寫出原本使用Visual Studio 2010內建的單元測試較難施行之案例,而且是以相當精簡的程式碼完成。

關於Typemock Isolator的詳細使用方法請參考官方文件。到此筆者已經將VS2010單元測試的部分大致說明,並且加上了Mock的部分使得開發人員可以以更精簡的方式撰寫單元測試。希望讀者能夠從這幾期專欄中對VS2010的單元測試有更進一步的了解,並且可以真正在開發過程中實踐。在此也特別感謝胡百敬老師協助校稿。

參考資源
●Professional Visual Studio 2010, Randolph, Nick Gardner, David Minutillo, Michael Anderson, Chris, John Wiley & Sons Inc
●MSDN, http://msdn.microsoft.com/zh-tw/library/default.aspx
●http://www.testingmentor.com/imtesty/2009/11/18/basic-blocks-arent-so-basic/
●http://docs.typemock.com/Isolator/##typemock.chm/Documentation/Welcome.htm