使用 Moq 測試.NET Core 應用 -- Mock 屬性


第一篇文章, 關於Mock的概念介紹: https://www.cnblogs.com/cgzl/p/9294431.html

第二篇文章, 關於方法Mock的介紹: https://www.cnblogs.com/cgzl/p/9300356.html

本文介紹Moq的使用.

使用的代碼: https://github.com/solenovex/Moq4-Tutorial-Code 里面的 03 Before 部分.

Mock屬性

屬性是指 get set property.

接着上文, 我在03 Before部分的代碼里做了一些修改.

首先IPhysicalExamination接口添加了IsMedicalRoomAvailable屬性:

其實現類:

屬性方法內依然沒有做實現.

 

添加的這個屬性在業務上的意思就是體檢室是否可以使用. 如果不可以使用的話, 那么球員的轉會操作應該被推遲.

所以還需要為轉會結果枚舉添加一個推遲:

 

最后在轉會審批邏輯里進行判斷, 如果體檢室不可用, 那么轉會就被推遲:

 

在單元測試里對屬性進行mock非常的簡單:

 

這個測試也會通過的:

 

遞歸Mock

修改一下IPhysicalExamination接口, 形成一個多層嵌套的屬性:

IPhysicalExamination --> IMedicalRoom --> IMedicalRoomStatus --> IsAvailable.

通過上面這一串來判斷體檢室是否可用.

 

相應的實現類也要修改:

 

轉會審批方法里也要修改:

 

而在單元測試的方法里, 肯定是報錯的:

 

按照正常的思路, 我們可能會這樣做:

就是從內到外一層一層的mock.

這么做是沒問題的, 測試也會通過:

 

但是這樣做很麻煩, 而Moq則提供了一種簡單的方式來處理這種多層的/遞歸的mock:

這樣寫即可. 測試同樣會通過:

 

為屬性設置默認值

但是, 問題來了, 我還有一些其它的單元測試方法, 它們也需要用到這個屬性, 現在它們的狀態是:

有的測試失敗是因為其MockBehavior是Strict的, 而其它的失敗則是因為里面出現了NullReferenceException.

 

針對這些情況, 我們可以這樣設定:

這樣設置之后, 它會返回屬性類型的默認值, 因為我沒有設定返回值.

雖然測試依然不通過, 這是因為邏輯上的問題, 而不會拋出異常:

 

針對這種情況, 還有一種更好的辦法. 我們可以為mock對象設定默認值:

把DefaultValue的值設為DefaultValue.Mock.

但是DefaultValue這個屬性只對引用類型起作用(對值類型不起作用), 像這種遞歸的mock, 它會遞歸的創建所需的引用類型, 但是最后的IsAvailable這個值類型是不起作用的.

測試:

因為最后一層是bool類型的, 是值類型, 所以上面的設置不起作用, 返回的是false. 所以測試沒通過.

 

那我就把它改成string類型好了:

審批方法:

然后再調試測試:

string是引用類型, 但是mock的值依然是null...??!!??

這是因為string是一個sealed class, 而DefaultValue.Mock只對接口, 抽象類和非sealed的class起作用....

不過測試仍然是可以通過的, 因為我改邏輯了:

 

注意, 這個默認值只對寬松(Loose) mock, 起作用.針對Strict mock, 仍然需要設定最后一層屬性的值.

 

屬性值變化跟蹤

需要添加一些代碼, 首先添加一個枚舉:

為接口添加屬性:

實現類:

然后在審批類里, 我設置了這個屬性的值:

 

上面的代碼也就是說, 我的mock對象的某個屬性在測試的時候它的值會發生變化. 而Moq可以記住這些mock屬性的變化的值.....

 

新寫一個測試:

這里使用mockObj.SetupProperty()方法來開始追蹤屬性. 這個測試會通過:

該方法也可以通過下面的寫法來為被追蹤的屬性設置默認值:

mockExamination.SetupProperty(x => x.PhysicalGrade, PhysicalGrade.Failed);.

 

如果這個對象上有很多屬性需要進行設置和追蹤, 那么可以使用:

mock.SetupAllProperties(); 這個方法:

 

注意, 這個方法應該最先調用, 否則的話其它的設置可能會被覆蓋.

 

本文完成的代碼在: https://github.com/solenovex/Moq4-Tutorial-Code 里面的03 After.

未完待續......


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM