Pregunta

Tengo un singleton al que se accede en mi clase a través de una propiedad estática como esta:OtherClassNotBeingTested.Instance.SomeInstanceMethod()

Me gustaría probar mi clase sin hacer uno de estos objetos. ¿Hay alguna forma de que los rinomocos devuelvan un trozo cuando el recibo de la propiedad estática Instance ¿se llama?

Para ser más claro, aquí está el código para la propiedad de instancia:

    /// <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;
        }
    }

Actualización: así es como terminé arreglándolo:

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

    }

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

        //Real Constructor here
    }
}

Mis pruebas unitarias llaman al segundo constructor. El código real llama al primer constructor. El código de la clase usa el campo local mcontrol en lugar del singleton. (Creo que esto se llama inyección de dependencia).

También refactoré el singleton según Tony el ponySugerencia.

¿Fue útil?

Solución

Espero que tu mInstance La variable se declara como volátil, de lo contrario su implementación de DCL está rota. En serio, ¿realmente necesitas ese nivel de pereza? Personalmente recomendaría algunos de los Patrones más simples disponibles.

Sin embargo, cuando se trata de burlarse, no, no puedes burlarse de llamadas estáticas con rinomacios. Hay algunas herramientas disponibles que permiten esto, como Típico, pero personalmente refactoraba la aplicación para que sea más comprobable en primer lugar.

Otra opción es tener un singleton de "trampa" donde pueda establecer el valor de la propiedad Singleton en su caso de prueba. Si hace que la propiedad devuelva una interfaz en lugar de la clase Singleton en sí, puede reemplazar el verdadero singleton con un simulacro.

Otros consejos

A pesar de otros rumores de que puedes burlarte de los singletons, vea mi respuesta a:

¿Cómo burlarse de un singleton estático?

En este caso, es aún más simple, porque no hay un constructor estático. Si su singleton implementa una interfaz ya, no habría necesidad de cambiar su código productivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top