Unit testing 实现一个假的NHibernate存储库

Unit testing 实现一个假的NHibernate存储库,unit-testing,nhibernate,repository-pattern,Unit Testing,Nhibernate,Repository Pattern,我正在使用StoryQ执行一些基本的集成测试,我们正在使用NHibernate作为我们的ORM。 开始时,我不知道NHibernate实现了存储库模式,所以我创建了自己的IRepository来运行集成测试 然而,考虑到NHibernate已经实现了存储库模式,我假设它是针对某种接口实现的。因此,如果我的假设是正确的,我想使用NHibernate的存储库接口 我已经尝试过搜索它,但我遇到了一些信息,要做到这一点,我需要使用ISession接口。因为我对NHibernate不是很了解,有人能解释一

我正在使用StoryQ执行一些基本的集成测试,我们正在使用NHibernate作为我们的ORM。 开始时,我不知道NHibernate实现了存储库模式,所以我创建了自己的IRepository来运行集成测试

然而,考虑到NHibernate已经实现了存储库模式,我假设它是针对某种接口实现的。因此,如果我的假设是正确的,我想使用NHibernate的存储库接口


我已经尝试过搜索它,但我遇到了一些信息,要做到这一点,我需要使用ISession接口。因为我对NHibernate不是很了解,有人能解释一下为什么我需要在ISession接口上实现我的假存储库吗?NHibernate中的IRepository等价物是什么?有没有更深入的教程?

我不确定核心NHibernate中哪里有一个IRepository接口?好的,没有,所以您可能会参考其他NHibernate方面的项目

这也不是嘲笑ISession的最佳方法。在我看来,最好的办法是使用一个真正的内存数据库,它完全由NHibernate支持。您可能需要检查如何配置NHibernate以在sqlite内存数据库上运行,这基本上只是在测试中配置NHibernate


这种方法的好处是,测试运行速度非常快,好像不涉及数据库一样,您不需要为了运行/驱动测试而将所有ORM功能和松散的特性都抽象出来。

NHibernate没有实现存储库模式。它取代了它

如果您有一个简单的数据库实现,SQLite内存数据库是不错的,但我发现事情很快就会变得麻烦,几乎到了使用SQLite就像使用存根/模拟ISession/ICriteria/等一样痛苦的地步

一个完美的例子是:在我最近的一个项目中,我使用PostgreSQL作为我的生产数据库,使用SQLite作为我的测试数据库,我需要扩展NHibernate来添加对最近添加到PostgreSQL的聚合函数的支持。弄明白如何添加这个本身就是一个故事,但我解决了。然后我不得不在SQLite中找到一个功能等价物。我需要一个聚合函数,它的工作方式与Postgres函数的工作方式完全相同。没有。我四处询问,得知有一些方法可以扩展NHibernate以在SQLite中伪造此函数。我还可以选择扩展SQLite来添加此功能

我想做的就是围绕我试图实现的场景编写两个,也许三个测试。最后,我花了太多时间试图确保两个系统之间的功能对等。为一个功能付出这么多的努力是不值得的。如果接下来我需要添加另一个函数,会发生什么


我认为SQLite很有用。这是一个非常好的轻量级数据库系统,我喜欢您可以方便地将其用作简单场景中的内存数据库。然而,除此之外,我不确定它是否值得使用。我认为从现在起,我将在所有环境中使用相同的数据库,即使这意味着对所有数据持久性逻辑进行较慢的集成测试。

我所采取的方法是实现一个IRepository和GenericRepository,包装ISession保存和删除方法。此外,GenericRepository还使用NHibernate的LINQ提供程序实现IQueryable。我的实现很大程度上借鉴了Javier Lozano的MVC Trubine项目。他的实施情况如下:

这适用于我需要的大约80%的查询。对于其余部分,我创建一个查询对象来包装查询。这样,我就可以使用ICriteria、IQuery、IQueryOver或LINQ,无论查询的需要如何。法比奥·莫洛在这里解释得很好:


这两种方法都可以很容易地模仿掉依赖关系。

事实上,我不知道核心NHibernate中是否有一个IRepository接口,这正是我要问的。我会尽量说清楚的。我也不想去嘲笑我的演讲。然而,我确实希望能够针对某种接口编写代码,这种接口允许我编写测试。使用SqlLite肯定是一种选择。你知道有什么教程可以让我开始学习吗?@DavidS是的…Ayende有一个用于此目的的基类,检查这里Google可能会提供更多链接谢谢你。这似乎就是我要找的。谢谢你。似乎我在这里有点不知所措,因为我对NHibernate还很陌生,另一位开发人员介绍了它,但乍一看,它确实使测试驱动开发变得更加困难。IME,当我用TDD碰壁时,通常是因为我缺少一个抽象。从持久化机制获取实体NHibernate,L
inq到SQL、EF、DataReader,无论是控制器、ViewModel还是演示者的独立关注点。我要做的是使存储库或查询实现一个接口,这样我就可以伪造它,并将这种依赖关系注入到我的控制器/ViewModel/Presenter中。我将其抽象为一个查询提供程序,它根据类型返回查询对象。很容易在测试中存根/模拟。@cs-原则上,我不介意对真实数据库进行测试,即使这意味着我的集成测试运行缓慢。所以我的问题是,在测试环境中如何切换到测试dB,在生产环境中如何切换到生产dB。我知道这可能是一个基本问题,但我对NHibernate不是很了解,甚至不知道从哪里开始。生产站点从web.config读取,测试从app.config读取。您可以在这些配置文件中为环境提供适当的配置。有意义吗?@cs-是的。谢谢。这确实回答了我的问题,但格林和哈迪的回答会为实现细节提供更多线索吗。