c# - No se puede crear una clase de simulacro para un tipo interno usando Rhino Mocks
unit-testing rhino-mocks (3)
¿Intentaste hacer que las partes internas de la asamblea sean visibles para los simulacros de Rhino?
[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]
Ver Miembros internos de Rhino Mocks 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 conjunto "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 (lo que también explica por qué 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 ensamblaje.
Por lo tanto, debe asegurarse de que el ensamblaje de la clase de destino haga que sus componentes internos sean visibles para el ensamblaje de proxy como tal (en AssemblyInfo.cs, por ejemplo):
Estoy usando Rhino Mocks como un marco de burla para las pruebas unitarias.
Tengo una clase llamada Asunto, 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 Asunto se define de la siguiente manera:
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 la 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 un conjunto InternalsVisible para la clase Subject y la clase StoreTests. Sin embargo, cuando se ejecuta el caso de prueba, lanza una excepción en var mockStore = MockRepository.GenerateMock (); diciendo que IStore no es público y, por lo tanto, no podría generar un simulacro.
Creo que esto es porque el IStore no es público. Sin embargo, ya que he establecido InternalsVisibleTo en el dll IStore, ¿no será suficiente para que StoreTests cree un simulacro para esa clase?
Ahora creo que este problema puede resolverse haciendo pública la interfaz de IStore. Sin embargo, dado que esta no es una opción para mí, ¿hay alguna otra forma de crear un simulacro para IStore?
Bueno, esto podría ser respondido, pero para mí 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 el menú Herramientas en Visual Studio: Herramientas externas: Agregar para nombre pongo "LongStrongName", pero pongo lo que creas adecuado:
(esta ruta, o donde el sn.exe es para ti):
Command:
C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bin/sn.exe
Arguments:
-Tp $(TargetPath)
(Haga clic en la casilla de verificación, salida a "Usar ventana de salida")
Ahora puede hacer clic en el proyecto, luego ir a herramientas y ir al menú "LongStrongName":
y VS dará salida:
Public key is 0240000048000009400000006020000002400005253413100040000010001009badbe86c32ec0
ec429f0b3909*********
Public key token is 6ccc051********
Abra el assembly.cs y agregue:
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
agregue los ensamblajes que necesite, y listo (tuve que poner múltiples ensamblajes).
Sí, debería ser suficiente para agregar lo siguiente en el archivo AssemblyInfo.cs de un ensamblaje bajo la prueba:
[assembly: InternalsVisibleTo("Tests.Assembly.Name")]
[assembly: InternalsVisibleTo("NUnit.Framework")]
[assembly: InternalsVisibleTo("Rhino.Mocks, PublicKey=00240000048000009400000006020000002400005253413100040000010001009D1CF4B75B7218B141AC64C15450141B1E5F41F6A302AC717AB9761FA6AE2C3EE0C354C22D0A60AC59DE41FA285D572E7CF33C320AA7FF877E2B7DA1792FCC6AA4EB0B4D8294A2F74CB14D03FB9B091F751D6DC49E626D74601692C99EAB7718ED76A40C36D39AF842BE378B677E6E4EAE973F643D7065241AD86ECC156D81AB")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]