实现一个假的NHibernate存储库

时间:2011-05-28 14:49:28

标签: unit-testing nhibernate repository-pattern

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

但是,考虑到NHibernate已经实现了Repository模式,我认为它是针对某种接口实现的。所以,如果我的假设是正确的,我想反对NHibernate的Repository接口。

我试图搜索它,但我遇到的信息是,为了做到这一点,我需要对抗ISession接口。由于我不太了解NHibernate,有人可以解释为什么我需要针对ISession接口实现我的假存储库吗? NHibernate中的IRepository等价物是什么?是否有一些教程可以更深入地解决这个问题?

3 个答案:

答案 0 :(得分:3)

NHibernate没有实现Repository模式。它取代了它。

如果你有一个简单的数据库实现,SQLite内存数据库是很好的,但是我发现事情很快就会变得很麻烦,几乎到了使用SQLite作为一种痛苦甚至更多的麻烦。它是存根/模拟ISession / ICriteria / etc。

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

我想要做的就是围绕我试图实现的场景编写两个,也许三个。我最终花了太多时间试图确保两个系统之间的功能等效。对于一个功能来说,不值得所有这些努力。如果在路上会发生什么,我需要添加另一个功能?

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

答案 1 :(得分:1)

我不确定核心NHibernate在哪里有一个IRepository接口(AFAIK没有)所以你可能会引用其他一些NHibernate端项目。

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

这种方法的好处是,测试以非常好的速度运行,好像没有涉及数据库,并且您不需要抽象掉所有ORM功能(以及松散的功能)只是为了运行/推动你的考试。

答案 2 :(得分:1)

我采用的方法是实现一个IRepository和GenericRepository,以包装ISession Save和Delete方法。此外,GenericRepository还使用NHibernate的LINQ提供程序实现IQueryable。我的实施大量借鉴了Javier Lozano的MVC Trubine项目。他的实施在这里:https://github.com/jglozano/mvcturbine/blob/master/src/Blades/NHibernate/MvcTurbine.NHibernate/GenericRepository.cs

这适用于我需要的大约80%的查询。其余的,我创建一个查询对象来包装查询。这样,我可以使用ICriteria,IQuery,IQueryOver或LINQ,无论查询需要什么。 Fabio Maulo在这里解释得非常好:http://fabiomaulo.blogspot.com/2010/07/enhanced-query-object.html

这两种方法都可以轻松地模拟掉依赖关系。