【问题标题】:Rhino Mocks - Stub a SingletonRhino Mocks - 存根单身人士
【发布时间】:2009-11-02 23:43:05
【问题描述】:

我有一个 Singleton,可以通过如下静态属性在我的类中访问:OtherClassNotBeingTested.Instance.SomeInstanceMethod()

我想在不制作这些对象之一的情况下测试我的课程。当静态属性 Instance 的 getter 被调用时,RhinoMocks 有没有办法返回存根?

为了更清楚,这里是 Instance 属性的代码:

    /// <summary>
    /// Make a property to allow the OtherClassNotBeingTested class 
    ///   to be a singleton 
    /// </summary>
    public static OtherClassNotBeingTested Instance
    {
        get
        {
            // Check that the instance is null
            //  NOTE: COMMENTS BELOW HAVE SHOWN THIS TO BE BAD CODE.  DO NOT COPY
            if (mInstance == null)
            {
                // Lock the object
                lock (mSyncRoot)
                {
                    // Check to make sure its null
                    if (mInstance == null)
                    {
                        mInstance = new OtherClassNotBeingTested();
                    }
                }
            }

            // Return the non-null instance of Singleton
            return mInstance;
        }
    }

更新: 这就是我最终修复它的方式:

class ClassBeingTested
{
    public ClassBeingTested(IGuiInterface iGui):this(iGui, Control.Instance)
    {

    }

    public ClassBeingTested(IGuiInterface iGui, IControl control)
    {
        mControl = control;

        //Real Constructor here
    }
}

我的单元测试调用第二个构造函数。实际代码调用第一个构造函数。类中的代码使用本地字段 mControl 而不是单例。 (我认为这称为依赖注入。)

我还按照 Tony the Pony 的建议重构了 Singleton。

【问题讨论】:

    标签: c# unit-testing mocking rhino-mocks rhino-mocks-3.5


    【解决方案1】:

    我希望你的 mInstance 变量被声明为 volatile,否则你的 DCL 实现会被破坏。说真的,你真的需要那种程度的懒惰吗?我个人会推荐一些simpler patterns available

    但是,当涉及到模拟时 - 不,您不能使用 RhinoMocks 模拟静态调用。有一些可用的工具可以实现这一点,例如 Typemock,但我个人首先会重构应用程序,使其更易于测试。

    另一种选择是使用“作弊”单例,您可以在其中设置测试用例中单例属性的值。如果你让属性返回一个接口而不是单例类本身,你可以用模拟替换真正的单例。

    【讨论】:

    • 这个结构是复制粘贴的。我将对其进行更改以遵循您链接中的模式。我想我将在单例分配的类中有一个变量。这样我就可以嘲笑它了。
    • 小马托尼的回答是正确的。我想补充一点,可测试性问题是单例模式失宠的原因之一。您可能需要考虑 DI/IoC(依赖注入/控制反转)容器框架,例如 UnityStructureMap - 这些可以创建具有类似单例的生命周期的普通旧对象。
    【解决方案2】:

    尽管有其他谣言可以模拟单身人士,但请参阅我的回答:

    How to Mock a Static Singleton?

    在这种情况下它更简单,因为没有静态构造函数。如果您的单例已经实现了接口,则无需更改您的生产代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多