近工作上的活是研究一下如何为一个历史代码工程添加单元测试,已经做完了,想抛砖引玉和大家分享一下结果,听听大家的反馈。
  该工程目前还是VS2010下的C#代码,虽然大量使用了继承,封装和多态,但对接口的应用非常少,所以基本上没办法用常见的Mock框架(如Moq, Rhino Mock,等)来写单元测试。
  考虑下来,解决方案无非两种:一是重构现有代码,通过接口(interface)来实现依赖注入(Dependency Injection, DI);二是寻找无需通过接口直接支持虚拟实体类的Mock框架,用来拦截对依赖对象的访问,返回预定的结果。采用方案一的话,优化了代码架构,从长远来说更好一些,但是工作量较大,还需要做大量的测试以保证不会改变现有代码功能。采用方案二的话,则不需要对现有代码做任何改动,只需要直接创建测试代码好了。因此方案二还是很有吸引力的,我按这个方向做了一些研究。
  我发现市面上暂时还没有开源的Mock框架(.NET单元测试相关)支持虚拟实体类,而收费的我也只找到Microsoft Fakes, TypeMock Isolator和Telerik JustMock这三个。三者虽然用法上有些差异,但是主要功能比较接近,差别主要体现在以下几个方面:
  1.从价格上来看:
  Microsoft Fakes,没有免费版,只有在VS2012/VS2013的Premium和Ultimate版中才能用,而我们的开发环境用的主要是Professional版的,升级到相应版本的话成本很高(VS2013的话Windows Store差价$1770,MSDN Subscription差价$4920)
  Telerik JustMock满足需求的版本价格是每个开发者$399,包含一年免费升级+支持,(参见Buy JustMock)
  TypeMock Isolator满足需求的版本价格是$799每个license,$150每年升级+支持,(参见Isolator Pricing)
  由于Fakes价格太高,而且还需要升级现有代码,我们直接不考虑了。当然如果已经在用相应版本的话,还是可以考虑的,毕竟微软自己的东西还是用起来方便的。
  2.从功能上看,根据我们的一个测试用例分别用TypeMock和JustMock试写了一下,发现JustMock更强大一些。
  我们的这个测试用例是要测某个时间值由于特殊原因不包含年份,因此从客户端传到位于不同时区的服务端时,在跨年时会被解析到错误的年份。比如:客户端位于GMT+8在2014/01/01 07:00:00时传了01/01 07:00:00过来,而服务端位于GMT,当时是2013/12/31 23:00:00,这个时间会被解析成2013/01/01 07:00:00。解析调用的是DateTime.ParseExact()方法。TypeMock对MSCorLib中类的虚拟只提供了有限的支持,不支持这个方法的虚拟。而JustMock在这方面则做得好一些,能够支持该方法。
  所以,我的终结论是要么重构代码,使用接口来实现依赖注入,那么基本上各种Mock框架都能用;要么买JustMock,不用动现有代码,直接加单元测试好了。
  还有其他一些细节的东西,时间有限改天再补充吧。