使用MbUnit3的[Rollback]针对单元测试它能够相互作用源码
-
22-08-2019 - |
题
背景:
我的团队致力于确保直接从结账时,我们的代码汇编和单元的测试成功运行。为促进这一和测试我们的一些它能够映射,我们增加了一个源码DB到我们的存储库,它是一面镜子我们的生产SQL服务器的2005年的数据库。我们正在使用最新的版本:MbUnit3(第一部分的迦流)、系统。数据。源码和原则才能享受它的全部好处.
问题:
我已经发现了下列单元的测试不起作用源码,尽管执行而无需麻烦对SQL服务器2005年。
[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));
}
除我正(只有当工作与源码):
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
当源码使用和[Rollback]属性并不是指定的,该试验还成功完成。
问题:
这是一个问题系统。数据。源码的执行情况的TransactionScope其MbUnit3用于[Rollback]或限制源码发动机?
是否有一些方式写入这一单元的测试,工作对源码,这将回退,以避免影响该数据库每次运行测试?
解决方案
检查,如果你不是在你的SQLite NHibernate的配置中缺少connection.release_mode=on_close
。 (参考文档)
BTW:总是处置您的ISession
和ISessionFactory
其他提示
这不是一个真正的回答你的问题,但可能是一个解决方案来解决这个问题。
我使用一个内存执行情况的sql精简为我的集成试验。我建立了构架和填补数据库之前,每一个测试。该架构的建立和初始数据填补发生的真快(不到0.01秒每次测试),因为它是一个存储器数据库。
为什么你使用物理数据库?
编辑:应回答关于上述问题:
1.) 因为我迁移我的架构和数据直接从SQL服务器2005年,我希望它保留在源的控制。
- 我推荐储存文件的数据库方案在和一个文件或脚本,创造样品数据源的控制。你可以产生的文件使用sql服务器的豪华管理表达,你可以产生它从你的映射它能够或者您可以使用的工具,如sql比较和你也许可以找到其他解决方案用于这一点,当你需要它。纯文本文件的存储容易的版本控制系统,然后完整的二进制数据库文件。
2.) 做一些有关在记忆源码发动机不同,这样,它将解决这个困难?
- 它可能会解决你的问题,因为你可以重新创建的数据库之前,每一个测试。你的数据库,并正在测试将在一个国家预期在每次试验之前执行。有一个好处是,没有需要以滚回你的交易,但我有运行类似的测试与在存储器sqllite和它的工作,如木.
沟[回滚]并使用 NDbUnit 。我用这个自己这个确切的情况,并已伟大的工作。