简体   繁体   English

使用nhibernate和内存中的sqlite db进行单元测试设置有什么问题?

[英]What is wrong with this set up for unit tests using nhibernate and an in-memory sqlite db?

I have an app written in c# using nhibernate with an sqlite DB. 我有一个使用带有sqlite DB的nhibernate用c#编写的应用程序。 For unit testing, I'm using xunit and an in-memory sqlite db. 对于单元测试,我使用xunit和内存中的sqlite db。

I'm aware that the in-memory DB is destroyed when the session is closed so for testing, I use a single session and keep it open for the duration of the test. 我知道内存数据库在会话关闭时被破坏,所以为了测试,我使用一个会话并在测试期间保持打开状态。 In most of my tests this works fine. 在我的大多数测试中,这都很好。

However, in a few cases, I need to test methods that make use of both ISession and IStatelessSession . 但是,在少数情况下,我需要测试使用ISessionIStatelessSession After a little research, I settled on something similar to the approach described here . 经过一番研究,我找到了类似于这里描述的方法的东西 So the IStatelessSession is created using the ISession 's connection like this: 所以IStatelessSession是使用ISession的连接创建的,如下所示:

statelessSession = factory.OpenStatelessSession(existingSession.Connection);

The problem is that this seems to cause some sort of conflict as soon as a change is persisted to the DB. 问题是,只要持续更改数据库,这似乎就会引起某种冲突。 If I do a transaction with session.SaveOrUpdate(new Entity() {...}) then that's fine but if I then do a statelessSession.Get<Entity>(1) then it will fail with the error message "collection is not associated with any session". 如果我使用session.SaveOrUpdate(new Entity() {...})那么这很好但是如果我然后执行statelessSession.Get<Entity>(1)那么它将失败并显示错误消息“collection is not not与任何会话相关联“。

Normally, this error would indicate that the session is closed, but in this case, both sessions are still open and active. 通常,此错误表示会话已关闭,但在这种情况下,两个会话仍处于打开和活动状态。

If I do session.Get<Entity>(1) then it returns the entity as expected. 如果我执行session.Get<Entity>(1)然后它按预期返回实体。 Initially, I thought this might be because the session and stateless session were somehow out of sync so I replaced session.SaveOrUpdate.. with statelessSession.Insert(new Entity() {...}) and reran the test. 最初,我认为这可能是因为会话和无状态会话在某种程度上不同步所以我用statelessSession.Insert(new Entity() {...})替换了session.SaveOrUpdate..并重新进行测试。 Strangely, this made no difference. 奇怪的是,这没有任何区别。 The regular session still works fine and the statelessSession is still broken. 常规会话仍然正常,statelessSession仍然被打破。

Finally, I've found a solution to this whole thing: 最后,我找到了解决这个问题的方法:

Eventually, I went back to my original query (a more complex query than the example above that returns multiple results) and tried various things while debugging through it, none of which shed any light on the problem. 最后,我回到了原始查询(比上面的示例更复杂的查询返回多个结果)并在通过它进行调试时尝试了各种各样的事情,但没有一个能够解决问题。 I then decided to remove the 'where' part of that query to see if it made any difference. 然后我决定删除该查询的“where”部分,看它是否有所不同。 Strangely, it did. 奇怪的是,确实如此。 It still failed, but this time I got a different exception: 'could not execute query', this also had an inner exception: 'possible non-threadsafe access to the session'. 它仍然失败,但这次我得到了一个不同的例外:'无法执行查询',这也有一个内部异常:'可能的非线程安全访问会话'。

The whole test runs on a single thread and I confirmed this by looking at the thread view when debugging. 整个测试在一个线程上运行,我通过在调试时查看线程视图来确认这一点。 So I thought I'd hit another brick wall. 所以我以为我会碰到另一堵砖墙。 However, after some googling, I found this blog post that describes the same problem and the solution: just update to the latest version of nhibernate! 然而,经过一些谷歌搜索,我发现这篇博文描述了同样的问题和解决方案:只需更新到最新版本的nhibernate!

I updated from 3.1.0 to 3.3.1 (thanks to NUGet, this was a breeze) re ran the test and it worked. 我从3.1.0更新到3.3.1(感谢NUGet,这是轻而易举的)重新运行测试,它工作。 Put the where clause back and the test passed. 放回where子句并通过测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在单元测试中使用内存 Sqlite 忽略嵌套事务? - How to ignore nested transactions using in-memory Sqlite on Unit Tests? 复制内存中的SQLite数据库以使单元测试更快 - Copy in-memory SQLite Database to make unit tests faster EntityFrameworkCore SQLite内存中的数据库表未创建 - EntityFrameworkCore SQLite in-memory db tables are not created SQLite正在为内存数据库创建磁盘文件 - SQLite is creating a disk file for In-memory DB 流畅的NHibernate:SQLite内存数据库和插入时生成的GUID - Fluent NHibernate: SQLite in-memory database and GUID generated on insert NHibernate从内存中SQLite数据库删除记录的问题 - NHibernate problems with deleting records from In-Memory SQLite database 使用Visual Studio Team Services通过内存中的SQL数据库运行单元/集成测试 - Running Unit / Integration tests through an in-memory SQL database using Visual Studio Team Services 在内存中模拟LinqToSql存储库以用于单元测试 - Mocking a LinqToSql repository in-memory for use in unit tests 在 Docker 容器中运行 SQL Lite 内存单元测试时出错 - Error Running SQL Lite In-Memory Unit Tests in Docker Container 如何设置内存存储库 - How to set up an in-memory repository
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM