Así, utilizando NUnit y RhinoMocks:No se puede obtener RhinoMocks para emitir una maqueta que sigue a la restricción de tipo genérico reglas
//Defines basic behavior of all persistable domain objects
public interface IDomainObject {...}
//defines domain objects specific to the Security DB
public interface ISecurityDomainObject : IDomainObject {...}
//Defines a basic transactional data Repository; there are multiple implementors
//which each close TRest to the interface that defines their DB's domain classes
public interface IRepository<TRest> : IDisposable where TRest:IDomainObject
{
IUnitOfWork BeginUnitOfWork();
void CommitUnitOfWork(IUnitOfWork unitOfWork);
void RollBackUnitOfWork(IUnitOfWork unitOfWork);
void Save<T>(T domainObject, IUnitOfWork unitOfWork) where T : class, TRest;
IQueryable<T> QueryFor<T>(IUnitOfWork unitOfWork) where T :class, TRest;
}
public interface ISecurityRepository:IRepository<ISecurityDomainObject> {}
public class SecurityRepository:ISecurityRepository
...
//This line breaks when run in an NUnit test
var securityRepository = MockRepository.GenerateMock<ISecurityRepository>();
...
El error que consigo es:
System.TypeLoadException : Method 'Save' on type 'ISecurityRepositoryProxyb8e21deb3cb04067a01ac5b63f7045af' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' tried to implicitly implement an interface method with weaker type parameter constraints.
at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Rhino.Mocks.MockRepository.MockInterface(CreateMockState mockStateFactory, Type type, Type[] extras)
at Rhino.Mocks.MockRepository.CreateMockObject(Type type, CreateMockState factory, Type[] extras, Object[] argumentsForConstructor)
at Rhino.Mocks.MockRepository.DynamicMock(Object[] argumentsForConstructor)
at Rhino.Mocks.MockRepository.<>c__DisplayClass7`1.<GenerateMock>b__6(MockRepository r)
at Rhino.Mocks.MockRepository.CreateMockInReplay(Func`2 createMock)
at Rhino.Mocks.MockRepository.GenerateMock(Object[] argumentsForConstructor)
at CSHD.Tests.Unit.Presentation.LoginTests.TestAuthenticationFails() in LoginTests.cs: line 138
Al intentar generar el simulacro en contra de la clase concreta, obtengo un error similar, esta vez en el método QueryFor(). Si intento redefinir los métodos que usan TRest en la interfaz ISecurityRepository, aparece una "System.BadImageFormatException: se intentó cargar un programa con un formato incorrecto. (Excepción de HRESULT: 0x8007000B)" que parece un paso atrás .
Creo que el problema principal es que RhinoMocks se confunde con los parámetros genéricos que se utilizan como restricciones de tipo genérico. No tengo ni idea de dónde se confunde y, por lo tanto, no sé cómo o si puedo desconfundirlo. Tengo una cobertura de prueba de integración adecuada que podría ignorar estas pruebas de unidades fallidas si es absolutamente necesario, pero obviamente prefiero corregirlas si puedo. ¿Tus pensamientos?
Gracias. Creo que simplemente ignoraré la prueba por el momento, y estaré atento a la próxima versión de Rhino Mocks. Mientras se arregle a partir del próximo lanzamiento, no me siento tan mal por hacerlo. – KeithS
Solo para confirmar la sugerencia de Ergwun, tuve el mismo problema. Revisé la fuente de Rhino y lo actualicé todo en la versión troncal de Castle, y el error está corregido. – FinnNk