【问题标题】:Using a Factory to replace instances by fakes from an Isolation Framework使用工厂用隔离框架中的假货替换实例
【发布时间】:2010-02-24 17:46:53
【问题描述】:

一个月前,我读完了“单元测试的艺术”一书,今天我终于有时间开始使用 Rhino Mocks 对一个服务进行单元测试,该服务向设备 (UDP) 发送/接收消息并从数据库。
当然,我想隔离数据库和 UDP 通信。

例如对于数据库访问,我们有一些带有静态方法的类,我们称之为:

  • AreaADBAccess
  • AreaBDBAccess
  • AreaCDBAccess

这些类具有执行数据库访问的静态方法。
为了能够对它们进行 stub,我将它们的方法设为 public virtual。

然后我开始重构代码,以便能够在代码上替换这些类的实例。
在尝试了不同的事情之后,我最终得到了一个看起来让事情变得如此简单的工厂类。

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 个地方重复方法头似乎没用。
谢谢!

【问题讨论】:

    标签: c# rhino-mocks factory isolation-frameworks


    【解决方案1】:

    也许您可以使用 Windsor、StructureMap 或 Ninject 等 IoC 容器,这将使您的生活更加轻松,事实上它们也可以作为您手动创建的“工厂”工作,但功能更强大。

    还有自动模拟容器,它会自动为您的类创建模拟依赖项,这样您就可以节省额外的代码行,并使您的测试不那么脆弱。

    关于是否需要接口而不是类的问题,基本上是依赖倒置原则,即高层模块(类)不应该依赖于低层模块(类),它们都应该依赖于抽象。接口就是那些抽象。 我建议你看看 S.O.L.I.D 原则,这会让你的生活更轻松,至少他们对我做了..

    【讨论】:

    • +1。是的,@paulya 似乎实现了他自己的服务定位器。有关 IoC 容器的列表,请参阅 hanselman.com/blog/…
    • 如果你保留一个接口,你需要用类的方法维护另一个文件。但我想你可以使用重构工具来帮助你维护?
    • 我想多一个接口文件是零成本。尤其是如果它使您的设计更加灵活和可扩展,这源于依赖倒置原则...... Resharper、CodeRush 或 event Vistual Studio 等工具内置在重构工具中,可以更轻松地管理这些文件......
    • @miensol:+1 提及 SOLID
    • @paulouya,你更喜欢哪一个:一个类 10.000 行错综复杂的代码,还是 50 个小型且易于理解的接口和具有明确职责的类文件?你应该停止担心创建新的源文件——小类是你的朋友。你是对的:像 R# 这样的重构工具让管理这些文件变得更加容易。
    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多