问题

假设有一个方法需要判断当前小时范围,代码如下:

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种方案相关推荐

  1. .Net 中如何测试静态方法

    大部分Mokc框架是不支持mock静态方法的,那我们如何测试静态方法呢? 下面这个类包含了一个静态方法: public class MyHelper {public static string Get ...

  2. 蓝桥杯真题 18省4-测试次数 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。 各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐

    问题描述 x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机. 各大厂商也就纷纷推出各种耐摔型手机.x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市 ...

  3. Nature封面:AI 机器人研发出了一种全新的化学催化剂

    来源:学术头条 本文约2262字,建议阅读5分钟. 本文介绍来自利物浦大学的研究人员,成功的开发了一款人工智能机器人化学家.这款机器人化学家可以同时考虑数十个维度的变量,每天工作 21.5 个小时,像 ...

  4. 《深度学习入门一》一入侯门深似海,深度学习深几许 2017-06-09 云栖社区 摘要: 当你和女朋友在路边手拉手一起约会的时候,你可曾想,你们之间早已碰撞出了一种神秘的智慧–深度学习。恋爱容易,相

    <深度学习入门一>一入侯门深似海,深度学习深几许 2017-06-09 云栖社区 摘要: 当你和女朋友在路边手拉手一起约会的时候,你可曾想,你们之间早已碰撞出了一种神秘的智慧–深度学习.恋 ...

  5. AI一分钟 | 马斯克证实:特斯拉私有化的幕后推手是沙特主权基金;DeepMind的AI可以检测出超过50种眼疾...

    ▌谷歌 DeepMind 的 AI 可以检测出超过 50 种威胁视力的眼疾  DeepMind 周一发布了一项研究,显示其在使用人工智能诊断眼部疾病方面取得的进展.该研究发表在自然科学杂志上,该研 ...

  6. python编码规范手册-Python官方竟然给出了一种编码规范PEP 8

    写在之前 每个人都有自己的代码风格,随着写的行数增加,自己对于代码的审美也会变的不一样,这就像是一个逐渐蜕变的过程,每过一段时间回头再去看看自己之前写的代码就会生出一种「这么丑的玩意儿竟然是我写的」这 ...

  7. javascript--弹出对话框 四种对话框 获得用户输入值 .

    让用户点击确定 取消.让用户输入值.打开指定窗口 alert("message") confirm("message") prompt("messag ...

  8. vue在生产环境、测试环境和开发环境,三种环境下配置不同的api地址

    vue在生产环境.测试环境和开发环境,三种环境下配置不同的api地址 我们大多数在开发的时候,都会有三种环境,一个是开发环境,一个是测试环境,一个是生产环境,我们打包的时候需要根据不同的环境去加载不同 ...

  9. 面试题目之:说出至少4种vue当中的指令和它的用法?

    说出至少4种vue当中的指令和它的用法? (1){{}} .v-html 和v-text ==> 非表单元素 {{}}:以{{data的属性名}}的方式直接使用在标签之间 例如: {{name} ...

最新文章

  1. 史上最强女游戏程序员
  2. 让Linux修改IP、DNS等可以更简单
  3. [AC自动机][dfs] 洛谷 P2444 病毒
  4. 国立大学 计算机,新加坡国立大学 计算机
  5. java虚拟机-程序计数器PC Register
  6. java 滚动显示信息_滚动显示文本的Java程序
  7. c 语言程序上机考试系统,计算机二级C语言上机考试操作步骤及流程
  8. Android学习笔记---29_构建soap协议内容,发送xml数据和调用webservice,手机号码归属地查询器
  9. vmware下虚拟机不能上网问题解决
  10. 汽车质量管理体系IATF 16949和培训及相关的标准(主要是电动汽车)
  11. 使用proteus8.9进行跑马灯程序仿真
  12. 用adb给华为mate10手机精简系统
  13. 小型微型计算机怎么样,电脑小主机怎么样,全方位分析小型电脑主机优缺点
  14. 从苏宁电器到卡巴斯基第06篇:我在佳木斯的日子(中)
  15. unfinished application
  16. 区块链毕设开题技术路线
  17. 办公室文秘试题 计算机,文秘计算机练习测验题.doc
  18. Creator3D:shader7_尽然还有双pass这波操作
  19. 构造函数能否被继承,为什么?
  20. 首届“全球创新创业教育论坛” 暨“大学三基工程”工作会议将于9月26-28日在湖南韶山召开

热门文章

  1. EqualLogic全攻略视频[(四)高级管理]
  2. decode 大于比较 小于_6 燃气输配系统6.3 压力不大于1.6Mpa的室外燃气管道城镇燃气设计规范 GB500282006(2020修订版)...
  3. python可迭代对象 迭代器生成器_Python可迭代对象、迭代器和生成器
  4. 高精度(压位+判负数+加减乘+读写)
  5. js----与浏览列表有关的对象(浏览器对象)
  6. emwin之错误使用控件函数导致死机现象
  7. JDBC学习笔记之JDBC简介
  8. Group Box组合框的简单使用 [大三TJB_708]
  9. 深度解析windows调试技术之一 [抓取user mode dump文件的几重境界]
  10. wp7开发官方教程和开发包