Unit testing 使用MbUnit3';s[Rollback]用于单元测试NHibernate与SQLite的交互
背景: 我的团队致力于确保直接从签出开始,我们的代码编译和单元测试就能成功运行。为了促进这一点并测试一些NHibernate映射,我们在存储库中添加了一个SQLite DB,它是生产SQL Server 2005数据库的镜像。我们正在使用最新版本的:MbUnit3(Gallio的一部分)、System.Data.SQLite和NHibernate 问题: 我发现下面的单元测试不适用于SQLite,尽管对SQLServer2005执行时没有遇到问题Unit testing 使用MbUnit3';s[Rollback]用于单元测试NHibernate与SQLite的交互,unit-testing,nhibernate,sqlite,mbunit,gallio,Unit Testing,Nhibernate,Sqlite,Mbunit,Gallio,背景: 我的团队致力于确保直接从签出开始,我们的代码编译和单元测试就能成功运行。为了促进这一点并测试一些NHibernate映射,我们在存储库中添加了一个SQLite DB,它是生产SQL Server 2005数据库的镜像。我们正在使用最新版本的:MbUnit3(Gallio的一部分)、System.Data.SQLite和NHibernate 问题: 我发现下面的单元测试不适用于SQLite,尽管对SQLServer2005执行时没有遇到问题 [Test] [Rollback
[Test]
[Rollback]
public void CompleteCanPersistNode()
{
// returns a Configuration for either SQLite or SQL Server 2005 depending on how the project is configured.
Configuration config = GetDbConfig();
ISessionFactory sessionFactory = config.BuildSessionFactory();
ISession session = sessionFactory.OpenSession();
Node node = new Node();
node.Name = "Test Node";
node.PhysicalNodeType = session.Get<NodeType>(1);
// SQLite fails with the exception below after the next line called.
node.NodeLocation = session.Get<NodeLocation>(2);
session.Save(node);
session.Flush();
Assert.AreNotEqual(-1, node.NodeID);
Assert.IsNotNull(session.Get<Node>(node.NodeID));
}
[测试]
[回滚]
公共void CompleteCanPersistNode()
{
//根据项目的配置方式,返回SQLite或SQL Server 2005的配置。
Configuration config=GetDbConfig();
ISessionFactory sessionFactory=config.BuildSessionFactory();
ISession session=sessionFactory.OpenSession();
节点=新节点();
node.Name=“测试节点”;
node.PhysicalNodeType=session.Get(1);
//SQLite在调用下一行后失败,出现以下异常。
node.NodeLocation=session.Get(2);
session.Save(节点);
session.Flush();
Assert.arnoteQual(-1,node.NodeID);
Assert.IsNotNull(session.Get(node.NodeID));
}
我得到的例外情况(仅在使用SQLite时)如下所示:
NHibernate.ADOException:无法打开连接-->
System.Data.SQLite.SQLite异常:
数据库文件已锁定。数据库已锁定
在System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
位于System.Data.SQLite.SQLiteDataReader.NextResult()处
在System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd,CommandBehavior)
在System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior)
在System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()中
位于System.Data.SQLite.SQLiteTransaction..ctor(SQLiteConnection连接,布尔延迟锁)
在System.Data.SQLite.SQLiteConnection.BeginDbTransaction(IsolationLevel IsolationLevel)中
在System.Data.SQLite.SQLiteConnection.BeginTransaction()中
在System.Data.SQLite.SqliteEnrolment..ctor(SQLiteConnection cnn,事务范围)
在System.Data.SQLite.SQLiteConnection.EnglistTransaction(事务事务处理)处
在System.Data.SQLite.SQLiteConnection.Open()处
在NHibernate.Connection.DriverConnectionProvider.GetConnection()处
在NHibernate.Impl.SessionFactoryImpl.OpenConnection()上
---内部异常堆栈跟踪的结束---
在NHibernate.Impl.SessionFactoryImpl.OpenConnection()上
在NHibernate.AdoNet.ConnectionManager.GetConnection()中
在NHibernate.AdoNet.AbstractBatcher.Prepare(IDbCommand cmd)中
位于NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
在NHibernate.Loader.Loader.GetResultSet(IDBST命令,布尔自动发现类型,布尔可调用,行选择,ISessionImplementor会话)
在NHibernate.Loader.Loader.DoQuery(ISessionImplementor会话、QueryParameters QueryParameters、Boolean returnProxies)
在NHibernate.Loader.Loader.DoQueryAndInitializeNonLazCollections(ISessionImplementor会话、QueryParameters QueryParameters、Boolean returnProxies)
在NHibernate.Loader.Loader.LoadEntity(ISessionImplementor会话、对象id、IType标识符类型、对象optionalObject、字符串optionalEntityName、对象optionalIdentifier、IEntypersister持久化器)
在NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor会话,对象id,对象optionalObject,对象optionalId)
在NHibernate.Loader.Entity.AbstractEntityLoader.Load(对象id、对象optionalObject、ISessionImplementor会话)
在NHibernate.Persister.Entity.AbstractEntityPersister.Load(对象id、对象optionalObject、锁模式锁模式、ISessionImplementor会话)
在NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent事件、IEntityPersister、EntityKey键加载、LoadType选项)
在NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent事件、IEntityPersister持久化程序、EntityKey keyToLoad、LoadType选项)
在NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent事件、IEntityPersister持久化程序、EntityKey keyToLoad、LoadType选项)
在NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent事件、IEntityPersister持久化程序、EntityKey keyToLoad、LoadType选项)
在NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent事件,LoadType LoadType)
在NHibernate.Impl.SessionImpl.FireLoad(LoadEvent事件,LoadType LoadType)
位于NHibernate.Impl.SessionImpl.Get(字符串entityName,对象id)
在NHibernate.Impl.SessionImpl.Get(类型entityClass,对象id)
位于NHibernate.Impl.SessionImpl.Get[T](对象id)
D:\dev\598\Code\test\unit\DataAccess.test\NHibernatePersistenceTests.cs
当使用SQLite且未指定[Rollback]属性时,测试也会成功完成
问题:
这是因为System.Data.SQLite实现了MbUnit3用于[Rollback]的TransactionScope,还是因为SQLite引擎的限制
是否有某种方法可以编写这个单元测试,使用SQLite,它将回滚,以避免每次运行测试时影响数据库?放弃[rollback]并使用。我自己在这个具体场景中使用了这个方法,效果非常好。这并不是对您问题的真正回答,但可能是解决问题的解决方案 我在集成测试中使用SQLLite的内存实现。在每次测试之前,我建立模式并填充数据库。模式创建和初始数据填充速度非常快(每个测试少于0.01秒),因为它是内存中的数据库 为什么要使用物理数据库 NHibernate.ADOException: cannot open connection ---> System.Data.SQLite.SQLiteException: The database file is locked database is locked at System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt) at System.Data.SQLite.SQLiteDataReader.NextResult() at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery() at System.Data.SQLite.SQLiteTransaction..ctor(SQLiteConnection connection, Boolean deferredLock) at System.Data.SQLite.SQLiteConnection.BeginDbTransaction(IsolationLevel isolationLevel) at System.Data.SQLite.SQLiteConnection.BeginTransaction() at System.Data.SQLite.SQLiteEnlistment..ctor(SQLiteConnection cnn, Transaction scope) at System.Data.SQLite.SQLiteConnection.EnlistTransaction(Transaction transaction) at System.Data.SQLite.SQLiteConnection.Open() at NHibernate.Connection.DriverConnectionProvider.GetConnection() at NHibernate.Impl.SessionFactoryImpl.OpenConnection() --- End of inner exception stack trace --- at NHibernate.Impl.SessionFactoryImpl.OpenConnection() at NHibernate.AdoNet.ConnectionManager.GetConnection() at NHibernate.AdoNet.AbstractBatcher.Prepare(IDbCommand cmd) at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session) at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) at NHibernate.Impl.SessionImpl.Get(String entityName, Object id) at NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id) at NHibernate.Impl.SessionImpl.Get[T](Object id) D:\dev\598\Code\test\unit\DataAccess.Test\NHibernatePersistenceTests.cs