NHibernate - 使用内存中的SQLite数据库进行业务层测试。如何更改数据库配置?

时间:2013-04-25 15:54:30

标签: sqlite fluent-nhibernate integration-testing in-memory-database

我使用Fluent NHibernate代码创建一个MySQL数据库SessionFactory。没有配置文件(配置中的连接字符串只有一个值 - 配置文件的connectionStrings部分)。

SessionFactory创建代码包含在数据层类中:SessionFactoryManager,它实现了一个单独的内部SessionFactory,数据和业务层使用它来通过SessionFactoryManager.OpenSession()获取所有会话。

我的一些业务层方法在内部调用SessionFactoryManager.OpenSession()以对Presentation层透明的方式创建会话。因此,在调用此方法时,没有涉及会话的参数或返回值(在使用这些业务层方法时,使表示层与“会话无关”)。

当我为Business层编写集成测试时,我的问题出现了:我想让它们在SQLite内存数据库上运行。我创建了一个SessionFactoryManager,它使用Fluent配置来配置SQLite数据库。

但是在测试那些内部创建会话的方法时,我无法告诉他们使用我的测试SessionFactory(配置为使用SQLite)。因此调用“真正的”SessionFactory,因此使用MySql数据库,而不是SQLite。

我正在考虑几种可能的解决方案,但它们似乎都没有。

我可以将数据层中的NHibernate配置迁移到配置文件,并为开发/生产和测试环境制作不同的NHibernate配置文件,但我真的更愿意继续使用Fluent代码。

我还可以修改我的数据层以使用单个配置值databaseMode或类似设置值来设置要使用的数据库:测试内存中或真实数据库。并编写一些switch(databaseMode)语句,如“case inMemory:{...内存SQLite的流畅代码......}案例标准:{...标准数据库的流畅代码......}”。我根本不喜欢这种方法,我不想仅仅出于测试目的修改我的数据层代码功能。

请注意,我没有测试数据层,而是测试业务层。对测试NHibernate映射,Dao或类似功能不感兴趣。我已经进行了单元测试,使用SQLite数据库运行正常。

此外,更改数据库不是我的应用程序的要求,所以我对实现允许我动态更改DBMS的重大更改不太感兴趣,我只是为了编写测试而满足了这个需求。

重点:使用内存中的SQLite时,所有新会话的数据库连接必须相同,否则新会话无法使用数据库对象。因此,在使用SessionFactory.OpenSession()创建新会话时,必须提供参数“connection”。但是此参数不应与非内存数据库一起使用。因此,交换机(databaseMode)应该用于任何单个会话创建!另一个我根本不喜欢的数据层代码更改。

我正在认真考虑放弃并使用真实数据库运行我的测试,或者至少在空数据库中运行我的测试,并为任何测试执行创建和删除其对象。但有了这个,测试执行肯定会变慢。有任何想法吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

最后我的解决方案是Inversion Of Control:我更改了我的数据层,因此我可以注入一个自定义的SessionFactoryBuilder类,使得Fluently.Configure(...)魔术。

在我的数据层中,我使用“真正的”MySqlSessionFactoryBuilder,在我的测试项目中,我编写TestMySqlFactoryBuilder或TestSQLiteSessionFactoryBuilder类,或者我需要的任何内容。

我仍然遇到SQLite功能问题,需要为所有会话使用相同的连接,并且必须在每个ISession.Open()调用中作为参数传递。到目前为止,我还没有修改我的数据层来添加该功能,但我希望将来能够这样做。可能通过向我的SessionFactory单例添加一个静态私有成员来存储用于创建SchemaExport的连接,以及一个静态私有布尔成员(如PreserveConnection)来声明此连接必须存储在该私有成员中并在每个ISession.Open()中使用。并且还包装ISession.Open()并确保没有直接打开会话。