2011-07-28 15 views
15

Estoy usando Rhino Mocks como un marco burlón para pruebas unitarias.No se puede crear una clase falsa para un tipo interno usando Rhino Mocks

Tengo una clase llamada Subject, que es la clase que quiero probar. Tiene una dependencia en IStore.

istore se define de la siguiente manera:

//internal interface : has InternalsVisible to both "Subject" 
//and "StoreTests" class namespaces 
internal interface IStore { 
    void Store(string name); 
    //other methods 
} 

y la clase de sujeto se define como sigue:

class Subject : IStore { 
    private IStore internalStore; 

    //constructor injection 
    void Subject(IStore store) { 
     internalStore = store; 
    } 

    void Store(string name) { 
     internalStore.Store(name); 
    } 

    //other methods 
} 

Mi clase de prueba usando RhinoMocks es el siguiente:

//test class 
class StoreTests { 
    Subject subject = new Subject(); 

    [Test] 
    public StoreTest() { 
     //Arrange 
     var mockStore = MockRepository.GenerateMock<IStore>(); 
     string testName = "test"; 
     mockStore.Expect(x => x.Store(testName)).Returns(null); 

     //Act 
     subject.Store(testName); 

     //Assert 
     mockStore.VerifyAllExpectations(); 
    } 

    //other test methods 
} 

En mi configuración, la interfaz se define como interna y tiene InternalsVisible configurado tanto para la clase Subject como para Sto devuelve la clase. Sin embargo, cuando el caso de prueba se ejecuta, arroja una excepción en var mockStore = MockRepository.GenerateMock(); diciendo que IStore no es público y, por lo tanto, no pudo generar un simulacro.

Creo que esto se debe a que el IStore no es público. Sin embargo, como he configurado InternalsVisibleTo en el dll del IStore, ¿no será suficiente que StoreTests cree un simulacro para esa clase?

Ahora creo que este problema se puede resolver haciendo pública la interfaz de IStore. Sin embargo, dado que esto no es una opción para mí, ¿hay alguna otra forma en que pueda crear un simulacro para IStore?

Respuesta

27

¿Usted intentó hacer la parte interna de montaje visibles para Rhino se burla?

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")] 

Ver Rhino Mocks Internal Members para más detalles.

Cuando se burla una clase, se genera una nueva clase en tiempo de ejecución que se deriva de la clase simulada. Esta clase generada reside en un ensamblaje "temporal" separado que se llama "DynamicProxyGenAssembly2". Por lo tanto, el atributo InternalsVisibleTo debe establecerse en el ensamblaje de destino para permitir el acceso a sus miembros internos desde el ensamblaje temporal; de lo contrario, el objeto simulado no puede anular el miembro interno ya que no tiene acceso a él (que también es el motivo por el cual el método simulado debe marcarse como virtual). Tenga en cuenta que esto es cierto incluso si la prueba de unidad y la clase probada están en el mismo conjunto.

Por lo tanto, es necesario asegurarse de que el conjunto de la clase de destino hace que sus componentes internos visibles para el ensamblado de proxy como tal (en AssemblyInfo.cs por ejemplo):

+1

¡Gracias por el enlace! Ahora funciona. – Santhosh

10

Sí que debería ser suficiente para añadir siguiendo los AssemblyInfo.cs archivo de un montaje según la prueba:

[assembly: InternalsVisibleTo("Tests.Assembly.Name")] 
[assembly: InternalsVisibleTo("NUnit.Framework")] 
[assembly: InternalsVisibleTo("Rhino.Mocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D1CF4B75B7218B141AC64C15450141B1E5F41F6A302AC717AB9761FA6AE2C3EE0C354C22D0A60AC59DE41FA285D572E7CF33C320AA7FF877E2B7DA1792FCC6AA4EB0B4D8294A2F74CB14D03FB9B091F751D6DC49E626D74601692C99EAB7718ED76A40C36D39AF842BE378B677E6E4EAE973F643D7065241AD86ECC156D81AB")] 
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 
+0

Esta respuesta también está bien. Marcar el otro como aceptado, solo porque proporciona un enlace a información adicional en el wiki. – Santhosh

3

Bueno, esto podría ser contestada, pero para yo no funcionó.

Así que esto es lo que hice para que funcione (podría ayudar a otros, e incluso a mí, en el próximo proyecto ...):

En menú de la herramienta en el estudio visual: herramientas externas: Añadir el nombre que puse "LongStrongName", pero poner lo que se siente en forma:

(este camino, o donde la sn.exe es para usted):

Command: 
    C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe 
Arguments: 
    -Tp $(TargetPath) 

(Haga clic en la casilla de verificación, la producción de "utilizar la ventana de salida")

Ahora usted puede hacer clic en el proyecto, y luego ir a herramientas e ir al menú "LongStrongName":

y VS seria:

Public key is  0240000048000009400000006020000002400005253413100040000010001009badbe86c32ec0 
ec429f0b3909********* 

Public key token is 6ccc051******** 

Abiertas las assembly.cs y añadir:

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] 

añadir lo que necesita asambleas, y listo (que tenía que poner varios ensamblados).

Cuestiones relacionadas