生成nhibernate模式后的SQLite数据库验证

时间:2010-05-10 16:26:56

标签: unit-testing nhibernate sqlite

在使用NHib的架构生成工具后,验证您的SQLite数据库是否真的在那里的最简单最有效的方法是什么?

干杯,
Berryl

修改

我希望有一些与ISession相关的东西(比如连接属性)可以测试;有时当运行一系列测试时,它看起来像是一个很好的会话(IsOpen和IsConnected都是真的),但是数据库不存在(对它的查询得到的错误就像'没有这样的表')。

编辑 - 我现在在做什么

连接字符串&其他cfg属性

public static Configuration GetSQLiteConfig()
    {
        return new Configuration()
            .SetProperty(ENV.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
            .SetProperty(ENV.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
            .SetProperty(ENV.ConnectionString, "Data Source=:memory:;Version=3;New=True;Pooling=True;Max Pool Size=1")
            .SetProperty(ENV.ProxyFactoryFactoryClass, typeof (ProxyFactoryFactory).AssemblyQualifiedName)
            .SetProperty(ENV.ReleaseConnections, "on_close")
            .SetProperty(ENV.CurrentSessionContextClass, typeof (ThreadStaticSessionContext).AssemblyQualifiedName);
    }

我现在如何测试db,因为缺少“更好”的东西(这会测试映射)

        public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
    {
        Check.RequireNotNull<ISessionFactory>(sessionFactory);
        Check.Require(session.IsOpen && session.IsConnected);

        _verifyMappings(sessionFactory, session);
    }

    private static void _verifyMappings(ISessionFactory sessionFactory, ISession session) {
        try {
            foreach (var entry in sessionFactory.GetAllClassMetadata())
            {
                session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
                    .SetMaxResults(0).List();
            }
        }
        catch (Exception ex) {
            Console.WriteLine(ex);
            throw;
        }
    }

        public static void VerifyAllMappings(ISessionFactory sessionFactory, ISession session)
    {
        Check.Require(!sessionFactory.IsClosed);
        Check.Require(session.IsOpen && session.IsConnected);

        try {
            foreach (var entry in sessionFactory.GetAllClassMetadata())
            {
                session.CreateCriteria(entry.Value.GetMappedClass(EntityMode.Poco))
                    .SetMaxResults(0).List();
            }
        }
        catch (Exception ex) {
            Debug.WriteLine(ex);
            throw;
        }
    }

每当打开一个新会话时,我都会在会话提供程序中生成模式:

        public ISession Session
    {
        get
        {
            var session = (ISession)CallContext.GetData(_lookupSessionKey);
            try
            {
                if (session == null)
                {
                    _log.Debug("Opening new Session for this context.");

                    session = FactoryContext.Factory.OpenSession();

                    if(RunTypeBehaviorQualifier != RunType.Production)
                        SchemaManager.GenerateNewDb(FactoryContext.Cfg, session.Connection);
                    CallContext.SetData(_lookupSessionKey, session);
                }
            }
            catch (HibernateException ex)
            {
                throw new InfrastructureException(ex);
            }
            return session;
        }
    }

现在这可能过度设计,但我需要多个数据库连接,而且我一直无法保持简单和安全。工作。这也是一个问题的很多信息,但也许其他人实际上已经把这一切都归结为一门科学。下面的测试在它自己的测试夹具中运行良好,但不能与其他测试结合使用。

    [Test]
    public void Schema_CanGenerateNewDbWithSchemaApplied()
    {
        DbMappingTestHelpers.VerifyAllMappings(_dbContext.FactoryContext.Factory, _dbContext.Session);
    }

2 个答案:

答案 0 :(得分:1)

Berryl,

据我所知,你正在使用不同的连接来对抗映射的实体。有没有要求您使用多个“真实”数据库连接的义务?我的意思是,您的测试可以共享相同的会话(逻辑上)吗?如果没有,您只需将数据库配置为:

      <property name="connection.connection_string">Data Source=NonTransactionalDB.txt;Version=3;New=True;Pooling=True;Max Pool Size=1;</property>

它的重要部分是汇集选项。由于每个会话都将使用相同的连接,因此每次重新创建模式都不会有问题。

但是,重要的是要记住,它会向您介绍有关交易的一些限制。 As SQLite can't handle more than one transaction per connection,并行运行测试可能会给您带来问题(例如“数据库文件被锁定”异常“)。

干杯,

菲利普

答案 1 :(得分:0)

Berryl,只是为了让它更容易想象,我会发布另一个答案。如果对你有帮助,请随意给我另一个。 :)

以下是我用来检查我的NH配置对象是否配置正确的代码。

        // assert: verify some properties just to see if connection properties were applyed ane entities mapped
        Assert.AreEqual<string>(cfg.Properties["connection.connection_string"], @"Server=localhost;Initial Catalog=MoveFrameworkDataNHibernate;User Id=sa;Password=sa");
        Assert.AreEqual<string>(cfg.Properties["dialect"], "NHibernate.Dialect.MsSql2000Dialect");
        Assert.IsNotNull(cfg.GetClassMapping(typeof(MappedEntity)));

真诚地,我也不安全,因为DB可以检查配置对象,但这是一种了解方式:是的,我的实体在那里,我指向正确的数据库。

我知道你害怕使用第二个SQLite连接并且数据库在前一个连接中暴露,所以你会得到不需要的异常,但据我所知,唯一的其他选项是检查你的实体是否是会有类似下面的代码。但是,当它引用SessionFactory时,它只能帮助上一个选项。

        tx.Session.SessionFactory.GetClassMetadata(typeof(MappedEntity)) != null

在这种情况下,我能想到的最后一个选项是使用EXISTS检查直接执行SQL到您的数据库。我不知道所有数据库实现之间的EXISTS命令是多么不可知,但是像我们在这里谈论的简单检查一样,这应该不是一个大问题。

希望这有帮助!

顺便说一句:这是jfneis。 Neis是姓氏。与薯条,炸薯条等无关。 :)

干杯。

菲利普