C#怎么测试静态方法?我给出了2种方案
生活随笔
收集整理的這篇文章主要介紹了
C#怎么测试静态方法?我给出了2种方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題
假設有一個方法需要判斷當前小時范圍,代碼如下:
public?class?Class1 {public?bool?SomeMethod(){var?hour?=?DateTime.Now.Hour;if?(hour?>=?9?&&?hour?<=?12){return?true;}return?false;} }但是,在做單元測試時,測試會偶爾失敗。
因為DateTime.Now沒法控制:
[Fact] public?void?Test1() {var?expect?=?new?Class1().SomeMethod();Assert.True(expect); }怎么辦?!
1.接口替代
常用的解決方案是使用接口替代靜態方法的直接調用,接口的實現可以使用依賴注入在運行時獲得:
public?interface?IClock {DateTime?Now?{?get;?} }public?class?Class1 {public?Class1(IClock?clock){this.Clock?=?clock;}public?IClock?Clock?{?get;?}public?bool?SomeMethod(){var?hour?=?Clock.Now.Hour;if?(hour?>=?9?&&?hour?<=?12){return?true;}return?false;} }可以手工或使用第三方Mock框架生成接口的實例,返回一個固定值,保證單元測試始終成功:
public?class?MockClock?:IClock {private?readonly?DateTime?_now;public?MockClock(DateTime?now){?this._now?=?now;?}public?DateTime?Now?=>?_now; }[Fact] public?void?Test1() {var?expect?=?new?Class1(new?MockClock(new?DateTime(1900,1,1,9,0,0))).SomeMethod();Assert.True(expect); }??2.Pose Mock
使用第三方Mock框架,比如Pose,直接Mock靜態方法。
無需修改業務代碼實現,只需在單元測試項目中引入nuget包Pose,然后修改測試用例代碼如下:
[Fact] public?void?Test1() {Shim?dateTimeShim?=?Shim.Replace(()?=>?DateTime.Now).With(()=>new?DateTime(1900,?1,?1,?9,?0,?0));PoseContext.Isolate(()?=>{var?expect?=?new?Class1().SomeMethod();Assert.True(expect);},?dateTimeShim); }結論
這2種方案各有優缺點:
接口替代
優點:實現簡單
缺點:所有調用原靜態方法的業務代碼都需要增加依賴注入參數
Pose Mock
優點:無需修改業務代碼
缺點:第三方庫不能保證Mock所有靜態方法成功
建議,針對新功能盡量使用接口,僅對不易改動的代碼才使用Pose Mock。
如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“,記住我!
總結
以上是生活随笔為你收集整理的C#怎么测试静态方法?我给出了2种方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方法参数修饰符in,out,ref
- 下一篇: .NET 6 预览版 7 Release