一个月前,我读完了《单元测试的艺术》一书,今天我终于有时间开始使用 Rhino Mocks 对一个服务进行单元测试,该服务向设备 (UDP) 发送/接收消息并从数据库中保存/加载数据。
当然,我想隔离数据库和 UDP 通信。
例如对于数据库访问,我们有一些带有静态方法的类,我们称它们为:
- 区域ADBAccess
- 区域BDBAccess
- 区域CDBAccess
这些类具有执行数据库访问的静态方法。
为了能够对它们进行存根,我将它们的方法设为公共虚拟。
然后我开始重构代码,以便能够在代码上替换这些类的实例。
在尝试了不同的事情之后,我最终得到了一个似乎让事情变得如此简单的工厂类。
public class ObjectFactory
{
private static Dictionary<Type, object> Instances = new Dictionary<Type, object>();
public static T GetInstance<T>() where T : new()
{
if(Instances.ContainsKey(typeof(T)))
return (T)Instances[typeof(T)];
return new T();
}
public static void SetInstance<T>(object obj)
{
Instances[typeof(T)] = obj;
}
}
然后在代码上,我可以使用
private AreaADBAccess DBAccess = ObjectFactory.GetInstance<AreaADBAccess>();
在测试方法上,我做了类似的事情
AreaADBAccess dbAccess = mocks.Stub<AreaADBAccess>();
using (mocks.Record())
{
...
}
ObjectFactory.SetInstance<AreaADBAccess>(dbAccess);
//Invoke the test method
...
这是第一个解决方案,我意识到可以以更好的方式完成。
您现在可以发表评论并指出最佳实践吗?
您能否也向我解释一下为什么我想要一个接口而不是将方法定义为虚拟的?在 2 个地方重复方法头似乎没用。
谢谢!