NHibernate测试,嘲笑ISession

Pra*_*ist 6 nhibernate iqueryable mocking

我正在使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Gar*_*ler 7

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

public interface IRepository<T>
{
    IQueryable<T> All();
    // whatever else you want
}
Run Code Online (Sandbox Code Playgroud)

像这样轻松实现:

public IQueryable<T> All()
{
    return session.Linq<T>();
}
Run Code Online (Sandbox Code Playgroud)

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

var result = repository.FindBy(x => x.Id == 1);
Run Code Online (Sandbox Code Playgroud)

你可以做:

var result = repository.All().Where(x => x.Id == 1);
Run Code Online (Sandbox Code Playgroud)

或者LINQ语法:

var result = from instance in repository.All()
             where instance.Id == 1
             select instance;
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在这种情况下拥有存储库有什么意义? (2认同)