1. 程式人生 > >單元測試(四)-隔離框架NSubstitute

單元測試(四)-隔離框架NSubstitute

靜態類 整體 txt 常用 style 實現 快捷 logger lambda表達式

之前學習了單元測試的基礎知識,以及樁對象和模擬對象的不同作用。但在實際應用中,往往不會直接手寫樁對象或者模擬對象,而是使用隔離框架動態的創建這些對象,這可以讓測試變得更簡便、快捷,還可以更好地應對復雜的測試。這裏學習的便是隔離框架的一種——Nsubstitute。

一 開始使用NSubstitute

在前面有一個測試場景為:使用LogAnalyzer.Analyze方法分析文件,如果文件名過短,就記錄日誌,為了測試LogAnalyzer類與ILogger實現之間的交互,需要手寫一個實現了ILogger接口的模擬對象,並針對這個模擬對象進行斷言。那麽現在使用NSubstitute來進行這一過程,測試代碼只有下面幾行就可以做到了。

技術分享

logger就是使用NSubstitute創建的模擬對象。Substitute靜態類動態負責創建偽對象,For 方法是產生偽對象的基本方法。最後一句中的logger.Receive方法在接口中並不存在,而是被NSubstitute擴充的,用於驗證方法是否被調用。logger.Received().LogError("Filename too short:a.txt")整體的意思便是:測試logger對象是否Receive對LogError方法的調用請求,而且傳遞的參數為"Filename too short:a.txt"。這是對模擬對象的測試方法。


二 設置偽對象的返回值

還可以設置方法在一定條件下的返回值

a) 全匹配

技術分享

rule.IsValidLogFileName("a.txt").Returns(true),指定了當方法IsValidLogFileName()被調用且參數為"a.txt"時返回結果為true

b) 類型匹配

技術分享

rule.IsValidLogFileName(Arg.Any<string>()).Returns(true),指定了當方法IsValidLogFileName()被調用且參數為string類型時返回結果為true,這樣匹配的範圍會更廣,這種指定方法也最常用。類型匹配主要使用Arg來指定

c) 返回異常

技術分享

還可以指定方法在一定的條件下返回何種異常,比如這兒的代碼中指定的條件為IsValidLogFileName()被調用且參數為string類型時,返回Exception("fake exception")。這兒的寫法與前面的有點區別,用到了lambda表達式


三 使用隔離框架的註意事項

a) 隔離框架的寫法會使代碼可讀性降低

b) 明確要驗證的對象,不要驗證錯誤的事情,也不要過度驗證

c) 盡量少用模擬對象,一個測試中最多出現一個模擬對象,但模擬對象存在時,要針對模擬對象進行斷言

d) 不要使用樁對象來驗證交互,這是模擬對象做的事情

參考資料:

The Art of Unit Testing with examples in C#, 2nd Edition by Roy Osherove

單元測試(四)-隔離框架NSubstitute