Nhibernate 如何使用结构映射模拟基类?

Nhibernate 如何使用结构映射模拟基类?,nhibernate,dependency-injection,mocking,fluent-nhibernate,structuremap,Nhibernate,Dependency Injection,Mocking,Fluent Nhibernate,Structuremap,我正在使用NHibernate,并且有许多存储库,它们都继承自一个基本的NHibernateRepository类。以下是我的一个存储库: public class StaffRepository : NHibernateRepository<IStaff>, { public IEnumerable<IStaff> GetBySiteRegionAndMonth(int siteId, int regionId, DateTime firstOfMonth)

我正在使用NHibernate,并且有许多存储库,它们都继承自一个基本的NHibernateRepository类。以下是我的一个存储库:

public class StaffRepository : NHibernateRepository<IStaff>, 
{
    public IEnumerable<IStaff> GetBySiteRegionAndMonth(int siteId, int regionId, DateTime firstOfMonth)
    {
        return Repository.Where(ab => ab.SiteId == siteId && ab.WorkDate >= firstOfMonth && ab.WorkDate < firstOfMonth.AddMonths(1));
    }
}
我的问题是,真正的
nhibernaterepositionary
仍然在测试中使用。根据我的注册,我正在使用real
StaffRepository

x.For<IStaffRepository>().Singleton().Use<StaffRepository>();
x.For().Singleton().Use();
我的所有其他测试类都被注入,但我认为这是有问题的,因为它是一个继承的类


我如何确保我的StaffRepository使用
TestNHibernateRepository
而不是
NHibernateRepository

尽管很容易创建一个伪实现,但您的单元测试将非常不可靠,因为您的存储库公开了
IQueryable
,这会导致特定的实现泄漏

这意味着,如果在单元测试中通过
IQueryable
使用LINQ to Objects实现,那么几乎所有通过
IQueryable
编写的LINQ查询都会成功,而在使用NHibernate查询提供程序时,它们很可能会失败

相反,您应该使用集成测试来测试依赖于
IRepository
的类,这意味着您要与真实的数据库进行通信,而不是与内存中的代理进行通信。单元测试应该在不同的级别上进行

即使
IQueryable
是一个接口,但它实际上并不是一个抽象,或者至少是一个抽象;A.因此,您应该确保仅在数据访问层中使用
IQueryable


我发现一个非常有效的解决方案是使用,其中查询对象(数据)是核心层的一部分,而它们的处理程序(以
IQueryable
的形式使用O/RM)是数据访问层的一部分。您可以对这些处理程序进行集成测试,而这些处理程序的使用者可以再次进行单元测试。

尽管很容易创建假实现,但您的单元测试将非常不可靠,因为您的存储库公开了
IQueryable
,这会导致特定的实现泄漏

这意味着,如果在单元测试中通过
IQueryable
使用LINQ to Objects实现,那么几乎所有通过
IQueryable
编写的LINQ查询都会成功,而在使用NHibernate查询提供程序时,它们很可能会失败

相反,您应该使用集成测试来测试依赖于
IRepository
的类,这意味着您要与真实的数据库进行通信,而不是与内存中的代理进行通信。单元测试应该在不同的级别上进行

即使
IQueryable
是一个接口,但它实际上并不是一个抽象,或者至少是一个抽象;A.因此,您应该确保仅在数据访问层中使用
IQueryable

我发现一个非常有效的解决方案是使用,其中查询对象(数据)是核心层的一部分,而它们的处理程序(以
IQueryable
的形式使用O/RM)是数据访问层的一部分。您可以对这些处理程序进行集成测试,而这些处理程序的使用者可以再次进行单元测试

x.For(typeof(IRepository<>)).Use(typeof(TestNHibernateRepository<>));
x.For<IStaffRepository>().Singleton().Use<StaffRepository>();