5

No estoy seguro si estoy haciendo la pregunta correcta, así que por favor tengan paciencia conmigo! Un poco de NHibernate noob.Fluido NHibernate - PersistenciaEspecificación del esquema HiLo

Estamos utilizando Fluido NH y tienen el siguiente esquema de generación de ID para todas las tablas

public class IdGenerationConvention : IIdConvention 
{ 
    public void Apply(IIdentityInstance instance) 
    { 
     var where = string.Format("TableKey = '{0}'", instance.EntityType.Name); 
     instance.GeneratedBy.HiLo("HiloPrimaryKeys", "NextHighValue", "1000", x => x.AddParam("where", where)); 
    } 
} 

Tenemos una secuencia de comandos SQL que genera la tabla HiloPrimaryKeys y la siembra de datos con el cual es ejecutado durante el despliegue. Esto está funcionando bien.

Ahora estoy tratando de escribir pruebas unitarias para verificar nuestra capa de persistencia, idealmente usando SQLite en la configuración de memoria para la velocidad. Así es como puedo configurar NH para las pruebas:

[SetUp] 
public void SetupContext() 
{ 
    config = new SQLiteConfiguration() 
      .InMemory() 
      .ShowSql() 
      .Raw("hibernate.generate_statistics", "true"); 

    var nhConfig = Fluently.Configure() 
      .Database(PersistenceConfigurer) 
      .Mappings(mappings => 
       mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>() 
      .Conventions.AddFromAssemblyOf<IdGenerationConvention>()); 

    SessionSource = new SessionSource(nhConfig); 
    Session = SessionSource.CreateSession(); 
    SessionSource.BuildSchema(Session); 
} 

El problema es que no sé cómo decirle a NHibernate acerca de nuestro script de implementación para que genere los datos del esquema y de semillas correctas durante las pruebas.

El problema específico que se ve es cuando se ejecuta la siguiente prueba PersistenceSpecification:

[Test] 
public void ShouldAddDocumentToDatabaseWithSimpleValues() 
{ 
    new PersistenceSpecification<Document>(Session) 
      .CheckProperty(x => x.CreatedBy, "anonymous") 
      .CheckProperty(x => x.CreatedOn, new DateTime(1954, 12, 23)) 
      .CheckProperty(x => x.Reference, "anonymous") 
      .CheckProperty(x => x.IsMigrated, true) 
      .CheckReference(x => x.DocumentType, documentType) 
      .VerifyTheMappings(); 
} 

que arroja la siguiente excepción:

TestCase ... failed: 
Execute 
NHibernate.Exceptions.GenericADOException: 
     could not get or update next value[SQL: ] 
     ---> System.Data.SQLite.SQLiteException: SQLite error 
     no such column: TableKey 

Así que mi deducción es que no se ejecute el script de implementación al verificar la especificación de persistencia.

¿Existe una solución existente para esta situación? Mi Google-fu parece haberme abandonado en este caso.

Respuesta

4

Como dijo Brian, puede ejecutar la secuencia de comandos de implementación una vez que se ha generado el esquema. Este código funciona bien para mí:

var config = new SQLiteConfiguration() 
     .InMemory() 
     .ShowSql() 
     .Raw("hibernate.generate_statistics", "true"); 

var nhConfig = Fluently.Configure() 
     .Database(config) 
     .Mappings(mappings => 
      mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>() 
     .Conventions.AddFromAssemblyOf<IdGenerationConvention>()); 

var SessionSource = new SessionSource(nhConfig); 
var Session = SessionSource.CreateSession(); 
SessionSource.BuildSchema(Session); 

// run the deployment script 
var deploymentScriptQuery = Session.CreateSQLQuery("ALTER TABLE HiloPrimaryKeys ADD COLUMN TableKey VARCHAR(255); INSERT INTO HiloPrimaryKeys (TableKey, NextHighValue) values ('Document', 1);"); 
deploymentScriptQuery.ExecuteUpdate(); 

El script de implementación se pudo cargar desde un archivo, etc ...

Edificio FNH configuración y la base de datos de esquema es tiempo de acción. La ejecución de prueba demandará una cantidad de tiempo inaceptable si el recuento de las pruebas que utilizan el esquema crece y el esquema y la configuración son construidos por cada clase de prueba.Tanto la configuración como el esquema deben compartirse entre todas las pruebas. Here es cómo lograr eso sin perder el aislamiento de prueba.

EDIT: Si se requiere más de una instancia de sesión en la prueba, entonces la agrupación de conexiones debe activarse o ambas sesiones deben crearse a través de la misma conexión. Detalles here ...

0

Negación: No soy un usuario de NHibernate ...

... Pero una posible solución sería la de ejecutar el script de implementación (o alguna variante de la misma) en el método de configuración de la prueba (usando una concha execute/Process.Start) o para ejecutarlo en su script de compilación justo antes de ejecutar estas pruebas. Es posible que necesite agregar limpieza en este caso si desea una base de datos nueva para cada prueba.

+0

Sí, lo intenté, pero parece que 'PersistenceSpecification' solo funciona con el esquema generado por NH, no con las alteraciones que haya realizado (hasta donde sé) –

0

Tenemos una secuencia de comandos SQL que genera la tabla HiloPrimaryKeys y la inicia con los datos que se ejecutan durante la implementación. Esto está funcionando bien.

¿Se puede crear una entidad que se mapee que represente esta tabla HiloPrimaryKeys y llenar esta tabla antes de que comiencen las pruebas? Podría poner esto en una clase base de la que heredarán todas sus otras pruebas para que no tenga que agregar esto a cada clase de prueba.

Esto es similar a la solución de Brian, pero en su lugar esta tabla se creará cuando realice su copia de seguridad al igual que el resto de sus tablas.

Cuestiones relacionadas