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
- 下一篇: 太神奇了!使用C#实现自动核验健康码:(