NHibernate Repository的单元测试策略

时间:2013-07-31 16:59:14

标签: c# wcf nhibernate repository-pattern

我在一个相当大的项目中使用NHibernate和Repository模式,并且我正在尝试建立我的服务层单元测试策略,并且遇到了一些问题。我可能不正确地接近单元测试,而且我也可能错误地接近存储库模式,但我不确定是哪个。

我的方案的简化子集如下所示:

public class UserRepository : RepositoryBase, IRepository 
{

   public UserRepository() {}
   public UserRepository( ISession sessionParam ) {
      session = sessionParam;   // member of repository base
   }

   public string GetUsernameFromEmail( string emailAddress ) {
      return session.QueryOver<Members>().List().Where( u => u.EmailAddress.ToLowerInvariant() == emailAdrress.ToLowerInvariant() ).FirstOrDefault().Username;
   }

}

我的单元测试概念是我会伪造NHibernate的ISession并传入一个返回符合我正在尝试测试的场景的用户列表(例如,电子邮件地址不区分大小写)(我也是不能让这与FakeItEasy一起工作,但这是另一个问题,我应该沿着这条路走下去)。记住我们不应该伪造我们不拥有的对象,我可以看到不想伪造ISession的逻辑,而且我已经阅读了很多关于不应该如何测试存储库的内容 - 那也是远远没有进行单元测试。

但即使在这个非常基本的情况下,存储库中的逻辑我想要进行单元测试。其他存储库方法可能具有更多逻辑(例如,数据验证等)。我知道我可以使用SqlLite或类似的东西来为reporitory构建相对快速的集成测试,但在我看来,这个逻辑应该是单元测试的。

依赖于存储库,有一个(WCF)服务层由Asp.Net MVC4站点使用。

在最好的世界中,我会在WCF层构建我的单元测试并假冒IRepository进行测试,但我不知道如何在不获取所有用户的情况下将此逻辑移动到服务层存储库并将它们返回到服务层,这看起来很荒谬。

所以我的问题是:我脑子里的整体架构到底有什么根本错误?

修改

在回答@ Wiktor-zychla的回答时,我的逻辑就是为什么我想要伪造ISession。在考虑这个特定的测试时,我希望我的存储库使用ISession的实现,该实现总是返回一个具有混合大小写的电子邮件地址和特定用户名的单个用户,传入一个小写的全部电子邮件地址,然后返回value是我指示我使用的假用户名。这样我就可以根据已知值测试我的逻辑 - 无论NHibernate在现实世界中的运行方式是不是我在这里关注的问题 - 测试存储库方法中的逻辑是。而且,我知道这是一个琐碎而天真的例子,可以通过许多其他方式解决 - 它只是代表我希望以后能够测试的更复杂的功能。

1 个答案:

答案 0 :(得分:2)

我认为你不应该试图伪造ISession。这没有多大意义 - NHibernate存储库是抽象概念的具体实现,您要测试的是这个具体实现是否正常而不是进一步抽象它并测试什么?一个不同的,假的linq实现,然后假装NH遵循它?

您的单元测试应该包含一个真正的数据库,然后可能在测试开始之前设置,以便您将临时ISession注入存储库,但ISession仍然指向真实的数据库。

另一方面,当您测试使用存储库的服务时,在服务层中注入另一个存储库实现是完全有效的。