最近
工作上的活就是研究一下如何为一个历史代码工程添加
单元测试,已经做完了,就想抛砖引玉和大家分享一下结果,听听大家的反馈。
该工程目前还是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,不用动现有代码,直接加单元测试就好了。