如何使用MOQ進行單元測試
使用MOQ來偽裝和隔離被依賴物件,從而提高被測物件的測試效果。
安裝
透過可以下載MOQ的最新版本。在SSL專案中,我們使用的是MOQ 3.1.416.3版本。在SCM中專案目錄下的Lib目錄下有該工具的二進位制版本。直接在單元測試專案中引用即可。
準備工作
如果你需要測試專案中的Internal成員,你需要在AssemblyInfo.cs中新增如下的Attribute:
?
#if DEBUG [assembly: InternalsVisibleTo( "DynamicProxyGenAssembly2,PublicKey=00240000048000009400000006020000002400005253" + "41310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266" + "654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c" + "4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" )] #endif
|
開始測試
一個單元測試的一般流程:
一般情況下,一個單元測試應該被分割為如下四個步驟:
準備
搭建環境
構造被測物件
初始化被測物件
構造Mock物件
初始化Mock物件
連線被測物件和依賴項
宣告期待
配置Mock(Mock
.Setup)物件以宣告該Mock物件期待被怎樣呼叫。 執行測試
呼叫被測物件的方法,完成測試步驟
校驗測試結果
呼叫校驗方法(Mock
.VerifyAll)對Mock物件上的期待動作進行校驗。 使用Assert方法對被測物件的狀態進行校驗。
一個單元測試的例子:
?
[TestMethod] public void TestNavigationSyncWithSelection() { // 測試如果修改Selection,那麼NavigationService.MoveCurrentTo方法應該被呼叫。 // 1. 準備 // 1.1 搭建環境 var c = new ServiceContainer(); var dataManager = new SpreadSheetDataManager(32, 8); // 1.2 構造被測物件 var selectionService = new SelectionService(); // 1.3 初始化被測物件 // 1.4 構造Mock物件 var mockNavigationService = new Mock // 1.5 初始化和配置Mock物件 c.AddService(mockNavigationService); mockNavigationService.Setup(s => s.CanMoveCurrentTo(It.IsAny .Returns( true ); // 1.6 連線被測物件和依賴項 c.AddService // 這裡隱式的將SelectionService和NavigationService連線在一起了。因為他們都被放到了一個容器裡面。 (selectionService as IService).Attach(c, dataManager); // 2. 宣告期待 mockNavigationService.Setup(s => s.MoveCurrentTo( new CellPosition(0, 1))); // navigationService的MoveCurrentTo方法期待被呼叫,並且引數為【0,1】。 // 3. 執行測試 selectionService.Select( new CellRange(0, 1, 2, 2)); // 4. 校驗 // 4.1 校驗Mock物件期待的動作被正確的呼叫了。 mockNavigationService.VerifyAll(); // 4.2 校驗被測物件的狀態。 Assert.AreEqual( new CellRange(0, 1, 2, 2), selectionService.CurrentSelection); }
|
推薦的單元測試寫法
目前的單元測試中,往往準備工作很複雜,反而真正測試的工作比較簡單。就像上面的例子中,準備的程式碼寫了8行,其它真正測試所關心的程式碼卻只有4行。這是一個非常不舒服的狀態。但是,我也沒有找到更好的方式來解決這個問題。只能說在架構上讓各個模組的依賴儘可能的小,從而減少準備工作的量。
另一方面,透過在程式碼中適當的增加幾行註釋,可以很好的幫助閱讀的人找到重點。我覺的如果整個團隊都採用一致的編碼習慣,閱讀效率會提高很多。如下是上面的例子去除了多餘的註釋後的版本。
?
[TestMethod] public void TestNavigationSyncWithSelection() { // 測試如果修改Selection,那麼NavigationService.MoveCurrentTo方法應該被呼叫。
|
擴充套件閱讀:Mocks Aren't Stubs
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2806261/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用jest進行單元測試
- 使用JUnit進行單元測試
- 使用 Spring Boot 進行單元測試Spring Boot
- 使用Jest進行React單元測試React
- 使用 Moq 測試.NET Core 應用 - Why Moq?
- Python中的單元測試框架:使用unittest進行有效測試Python框架
- 使用 Moq 測試.NET Core 應用 -- Mock 行為Mock
- 使用Angular CLI進行單元測試和E2E測試Angular
- Jest & enzyme 進行react單元測試React
- 如何對Spring MVC中的Controller進行單元測試SpringMVCController
- 在C#中進行單元測試C#
- [譯]對 React 元件進行單元測試React元件
- 使用SAP CRM mock框架進行單元測試的設計Mock框架
- 使用FakeAsync對Angular非同步程式碼進行單元測試Angular非同步
- 如何執行指定的單元測試
- JavaScript 測試教程-part 1:用 Jest 進行單元測試JavaScript
- 使用 Moq 測試.NET Core 應用 -- 其它
- 使用karma和jasmine配合phantom瀏覽器進行單元測試ASM瀏覽器
- 使用 Moq 測試.NET Core 應用 -- Mock 方法Mock
- 如何對第一個Vue.js元件進行單元測試 (上)Vue.js元件
- 如何對第一個Vue.js元件進行單元測試 (下)Vue.js元件
- FastAPI(43)- 基於 pytest + requests 進行單元測試ASTAPI
- 使用Github Copilot生成單元測試並執行Github
- 使用 PyHamcrest 執行健壯的單元測試REST
- go 單元測試進階篇Go
- 使用 Moq 測試.NET Core 應用 -- Mock 屬性Mock
- 如果利用 python 對 java 程式碼進行 單元測試?PythonJava
- Springboot整合JUnit5優雅進行單元測試Spring Boot
- 測試 之Java單元測試、Android單元測試JavaAndroid
- 單元測試工具 TestNG 使用
- 如何寫好單元測試
- 測試員進階技能:如何有效地利用單元測試報告?測試報告
- Angular單元測試如何只執行指定的測試用例,提高測試速度Angular
- 使用python對oracle進行簡單效能測試PythonOracle
- 使用CountDownLatch或迴圈屏障對多執行緒程式碼進行單元測試 -XebiaCountDownLatch執行緒
- 單元測試如何測試私有方法_1
- 如何測試 Flutter 應用? ー 單元測試Flutter
- 單元測試-一份如何寫好單元測試的參考