6

我正在使用 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,我想在内存中查询以测试我的 Linq 查询代码,而无需访问数据库。而且我不确定这会是什么样子。我是否编写自己的 IQueryable 实现?如果是这样,有人为这种方法做过吗?还是我需要看看其他途径?

谢谢!

4

2 回答 2

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;

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

正如您所指出的,这样做的目的是让您在不涉及数据库的情况下测试查询的逻辑,这会大大减慢它们的速度。

于 2009-01-15T22:19:19.833 回答
0

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

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

于 2009-01-15T21:44:08.237 回答