unit-testing - Fluent NHibernate - HiLo 方案的 PersistenceSpecification

标签 unit-testing nhibernate sqlite fluent-nhibernate persistence

不确定我问的问题是否正确,所以请多多包涵!一点 NHibernate 新手。

我们正在使用 Fluent NH 并且所有表都有以下 id 生成方案

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));
    }
}

我们有一个 SQL 脚本,它生成 HiloPrimaryKeys 表并使用在部署期间运行的数据为它做种子。这工作正常。

我现在正在尝试编写单元测试来验证我们的持久层,最好在内存配置中使用 SQLite 以提高速度。这是我为测试配置 NH 的方式:

[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);
}

问题是我不知道如何告诉 NHibernate 我们的部署脚本,以便它在测试期间生成正确的模式和种子数据。

我遇到的具体问题是在运行以下命令时 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();
}

抛出以下异常:

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

所以我的推断是它在检查持久性规范时没有运行部署脚本。

对于这种情况是否有现成的解决方案?我的 Google-fu 似乎在这个问题上抛弃了我。

最佳答案

正如 Brian 所说,您可以在构建架构后运行部署脚本。这段代码很适合我:

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();

部署脚本可以从文件等加载...

构建 FNH 配置和数据库模式是一项耗时的操作。如果使用模式的测试数量增加并且模式和配置由每个测试类构建,则测试套件的执行将花费 Not Acceptable 时间。配置和模式都应该在所有测试之间共享。 Here是如何在不失去测试隔离的情况下实现这一点。

编辑: 如果测试中需要多个 session 实例,则应打开连接池,或者应通过同一连接创建两个 session 。详情 here ...

关于unit-testing - Fluent NHibernate - HiLo 方案的 PersistenceSpecification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5632165/

相关文章:

iOS - UIViewController 中的依赖注入(inject)

performance - NHibernate插入具有代理关联的实体而不获取

php - SQL-查询帮助:查找局部最大值

java - 用java设置sqlite(导入org.sqlite.SQLite无法解析)

nhibernate - 从父集合中删除子记录

sqlite - 需要从insert语句向sqlite表中插入大量数据

c# - 使用 Moq 获取 UnitTest 中调用方法的返回值

java - stub 类仍然像通常调用的那样运行

unit-testing - 如何对 Flutter TextFormField maxlines 进行单元测试

c# - 如何通过 NHibernate 从表中获取数据?