Burlarse de una isesión de NHibernate con Moq


Estoy empezando un nuevo proyecto con NHibernate, ASP.NET MVC 2.0 y StructureMap y usando NUnit y Moq para pruebas. Para cada uno de mis controladores tengo un único constructor público en el que se está inyectando una ISession. La aplicación en sí funciona bien, pero en términos de pruebas unitarias, esencialmente tengo que simular una ISession para probar los controladores.

Cuando intento simular la isesión con MOQ obtengo el siguiente mensaje de error:

Solo propiedad se admiten accesos en invocaciones intermedias

Parece que mi problema está esperando la Lista de usuarios del método framework createQuery, pero después de buscar en Google el problema ahora estoy más claro.

Tengo dos preguntas:

1) ¿Es esta la forma INCORRECTA de simular la inyección de dependencia de una isesión

2) ¿Hay alguna forma de modificar el código para que pueda devolver mi lista

            [Test]
            public void DummyTest()
            {

                var mock = new Mock<ISession>();
                var loc = new Mock<User>();
                loc.SetupGet(x => x.ID).Returns(2);
                loc.SetupGet(x => x.FirstName).Returns("John");
                loc.SetupGet(x => x.LastName).Returns("Peterson");

                var lst = new List<User> {loc.Object};
                mock.Setup(framework => framework.CreateQuery("from User").List<User>()).Returns(lst);

                var controller = new UsersController(mock.Object);
                var result = controller.Index() as ViewResult;
               Assert.IsNotNull(result.ViewData);
            }

Tenga en cuenta que estoy bastante seguro de que podría crear un código duro lista de usuarios (en lugar de burlarse de un Usuario individual y agregarlo a una lista), pero pensé que dejaría el código como lo tengo ahora mismo.

Además, la acción Index de este controlador en particular esencialmente ejecuta la llamada createQuery imitada anteriormente para devolver todos los usuarios en la base de datos. Este es un ejemplo artificial - no lea nada en los detalles.

Gracias de antemano por su ayuda

Editar: En respuesta al siguiente comentario, estoy agregando la pista de apilamiento para el error. Además, todas las propiedades de la clase User son virtuales.

Caso de prueba 'Beta.Prueba.Unidad.Controladores.Usercontrolertest.Details_InValidIndex_ReturnsNotFoundView" fallo: Sistema.NotSupportedException : Solo se admiten accesos a propiedades en invocaciones intermedias en un configuración. Expresión no soportada marco.createQuery ("de usuario"). en Moq.Burla.AutoMockPropertiesVisitor.VisitMethodCall (MethodCallExpression m) at Moq.Expresionvisitor.Visita (Expresión cad) at Moq.Burla.AutoMockPropertiesVisitor.VisitMethodCall (MethodCallExpression m) at Moq.Expresionvisitor.Visita (Expresión cad) at Moq.Burla.AutoMockPropertiesVisitor.SetupMocks(Expresión expression) at Moq.Burla.GetInterceptor (LambdaExpression lambda, Mock mock) en Moq.Burla. c _ _ DisplayClass12 2.<Setup>b__11() at Moq.PexProtector.Invoke[T](Func 1 función) en Moq.Burla.Configuración [T1, TResult] (Mock mock, Expresión 1 expression) at Moq.Mock 1.Setup [TResult] (Expresión ' 1 expresion) Controladores\UserController Test.cs (29,0): en Beta.Prueba.Unidad.Controladores.Usercontrolertest.Details_InValidIndex_ReturnsNotFoundView ()

Author: JP., 2009-12-01

2 answers

A continuación se muestra la solución que se me ocurrió que parece funcionar perfectamente. Una vez más, no estoy probando NHibernate y no estoy probando la base de datos - simplemente quiero probar los controladores que dependen de NHibernate. El problema con la solución inicial parece ser el hecho de que estaba llamando a un método, así como leer el miembro de la lista de la sesión en la llamada de configuración de MOQ. Rompí estas llamadas dividiendo la solución en un QueryMock y un Simulacro de sesión (create query devuelve un objeto IZERY). Un transaction mock también fue necesario ya que es una dependencia (en mi caso) de la sesión...

        [Test]
        public void DummyTest()
        {
            var userList = new List<User>() { new User() { ID = 2, FirstName = "John", LastName = "Peterson" } };
            var sessionMock = new Mock<ISession>();
            var queryMock = new Mock<IQuery>();
            var transactionMock = new Mock<ITransaction>();

            sessionMock.SetupGet(x => x.Transaction).Returns(transactionMock.Object);
            sessionMock.Setup(session => session.CreateQuery("from User")).Returns(queryMock.Object);
            queryMock.Setup(x => x.List<User>()).Returns(userList);

            var controller = new UsersController(sessionMock.Object);
            var result = controller.Index() as ViewResult;
            Assert.IsNotNull(result.ViewData);
        }
 20
Author: JP.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-02 04:51:40

En lugar de burlarse del Session, uno podría considerar la creación de un Configuration diferente para las pruebas unitarias. Esta prueba unitaria Configuration utiliza una base de datos rápida en proceso como SQLite o Firebird. En la configuración del fixture, se crea una nueva base de datos de prueba completamente desde cero, se ejecutan los scripts para configurar las tablas y se crea un conjunto de registros iniciales. En la configuración por prueba, abre una transacción y en el desmontaje posterior a la prueba, revierte la transacción para restaurar la base de datos a su estado anterior. En un sentido, usted no se está burlando de la Session, porque eso se pone complicado, pero se está burlando de la base de datos real.

 18
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-02 02:06:36