我使用 Fluent NHibernate 代码创建 MySQL 数据库 SessionFactory。没有配置文件(配置中的连接字符串只有一个值 - 配置文件的 connectionStrings 部分)。
SessionFactory 创建代码包含在数据层类中:SessionFactoryManager,它实现了一个单例内部 SessionFactory,数据层和业务层使用它通过 SessionFactoryManager.OpenSession() 获取所有会话。
我的一些业务层方法在内部调用 SessionFactoryManager.OpenSession() 以对表示层透明的方式创建会话。因此,当调用此方法时,没有涉及会话的参数或返回值(在使用这些业务层方法时保持表示层“与会话无关”)。
当我为业务层编写集成测试时,我的问题出现了:我想让它们在 SQLite 内存数据库上运行。我创建了一个使用 Fluent 配置来配置 SQLite 数据库的 SessionFactoryManager。
但是在测试那些在内部创建会话的方法时,我不能告诉他们使用我的测试 SessionFactory(配置为使用 SQLite)。所以调用了“真正的”SessionFactory,所以使用的是 MySql 数据库,而不是 SQLite。
我正在考虑几种可能的解决方案,但似乎没有一个是正确的。
我可以将数据层中的 NHibernate 配置迁移到配置文件,并为开发/生产和测试环境制作不同的 NHibernate 配置文件,但我真的更愿意继续使用 Fluent 代码。
我还可以修改我的数据层以使用单个配置值、databaseMode 或类似值,以设置要使用的数据库:测试内存或真实数据库。并编写一些 switch(databaseMode) 语句,例如“case inMemory: { ... fluent code for in-memory SQLite ... } case standard: { ... fluent code for standard database ... }”。我根本不喜欢这种方法,我不想仅仅为了测试目的而修改我的数据层代码功能。
请注意,我不是在测试数据层,而是在测试业务层。对测试 NHibernate 映射、Dao 或类似功能不感兴趣。我已经对此进行了单元测试,可以使用 SQLite 数据库运行。
此外,更改数据库不是我的应用程序的要求,因此我对实现允许我动态更改 DBMS 的重大更改不太感兴趣,我只是为了编写测试才来这个需要。
重要的一点:当使用内存 SQLite 时,所有新会话的数据库连接必须相同,否则数据库对象对新会话不可用。因此,当使用 SessionFactory.OpenSession() 创建新会话时,必须提供参数“连接”。但此参数不应与非内存数据库一起使用。所以 switch(databaseMode) 应该用于任何单个会话的创建!另一个我完全不喜欢的数据层代码更改。
我正在认真考虑放弃并使用真实数据库运行我的测试,或者至少在一个空数据库上运行我的测试,并为任何测试执行创建和删除它的对象。但是有了这个,测试执行肯定会变慢。有任何想法吗?提前致谢。