NHibernate测试,嘲笑ISession

时间:2009-01-15 20:46:41

标签: nhibernate mocking iqueryable

我正在使用NHibernate和Rhinomocks并且无法测试我想要的内容。我想在不命中数据库的情况下测试以下存储库方法(其中_session作为ISession注入到存储库中):

public class Repository : IRepository
{
    (... code snipped for brevity ...)

    public T FindBy<T>(Expression<Func<T, bool>> where)
    {  
        return _session.Linq<T>().Where(where).FirstOrDefault();
    }
}

我最初的方法是模拟ISession,并在调用Linq时返回IQueryable存根(手动编码)。我有一个客户对象的IList,我想在memeory中查询以测试我的Linq查询代码而不会访问db。我不确定这会是什么样子。我是否编写自己的IQueryable实现?如果是这样,有人为这种方法做了这个吗?或者我是否需要查看其他途径?

谢谢!

2 个答案:

答案 0 :(得分:7)

我是如何完成此测试的,不是将表达式传递给存储库,而是公开IQueryable,为存储库提供如下界面:

public interface IRepository<T>
{
    IQueryable<T> All();
    // whatever else you want
}

像这样轻松实现:

public IQueryable<T> All()
{
    return session.Linq<T>();
}

这意味着不要在存储库中调用您的方法,而不是:

var result = repository.FindBy(x => x.Id == 1);

你可以这样做:

var result = repository.All().Where(x => x.Id == 1);

或LINQ语法:

var result = from instance in repository.All()
             where instance.Id == 1
             select instance;

这意味着您可以通过直接模拟存储库来获得相同的测试,这应该更容易。你只需要让mock返回你创建的列表并调用AsQueryable()。

正如您所指出的,这一点是让您测试查询的逻辑而不涉及数据库,这会大大减慢它们的速度。

答案 1 :(得分:0)

从我的观点来看,这将被视为集成测试。 NHibernate有自己的测试,它通过,在我看来,你正试图在自己的测试套件中复制一些这些测试。我要么将NHibernate代码和测试添加到你的项目中,然后将它们与它们的测试一起添加,如果它们没有一个非常相似的话,并使用它们的测试方法或将其移动到Integration测试场景并点击数据库中。

如果只是因为你正在使用NHibernate,你不想设置数据库来测试你的运气。通过一些谷歌搜索,你可以找到很多例子,说明如何使用SQLite“有点”对数据库进行集成测试,但将其保存在内存中。