3

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

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

为了更清楚,这里是 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。

4

2 回答 2

4

尽管有其他谣言你可以嘲笑单身人士,请参阅我对以下内容的回答:

如何模拟静态单例?

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

于 2013-09-24T16:14:50.177 回答
4

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

然而,当涉及到模拟时——不,你不能用 RhinoMocks 模拟静态调用。有一些可用的工具可以做到这一点,例如Typemock,但我个人首先会重构应用程序以使其更具可测试性。

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

于 2009-11-02T23:49:40.970 回答