模拟实体框架存储库模式



我有一个定义为:的接口

 public interface IRepository<TEntity> where TEntity : BaseEntity
{
   ...
    IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "");
    ...
}

我的实现方式是:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity
{
    internal MyContext context;
    internal DbSet<TEntity> dbSet;
    public Repository(MyContext context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }
    public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<TEntity> query = dbSet;
        if (filter != null)
        {
            query = query.Where(filter);
        }
        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }
        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }
}

最后是我的代码:

Repository.Get(r =>
            r.SourceOrganisationId == id,
            null, // No ordering
            "DestinationOrganisation") // Include the company
            .Select(d => d.DestinationOrganisation).OrderBy(c => c.Name);

我想对我的查询进行单元测试,以确保我得到了正确的where子句,并且在结果中包含了一个额外的实体。

我一直在研究如何使用Moq模拟DbContext和DbSet,但看不出如何仍然具有includes的EF功能。我发现的大多数例子都是模仿一个简单的GetById。基本上我不想模拟EF,只是让它从内存中读取,而不是从Db中读取。

有什么想法吗?

感谢

经过更多的研究,我意识到我想做的是不可能的。

我想要的是用内存存储来模拟DB,然后测试我的查询是否工作,包括Include方法(例如,有些测试包含相关实体,有些则不包含)。我不想模拟Include,实际上我想让它根据我的内存列表来实现。这是不可能的,因为从以下方面来看:

这种差异的一个例子是加载相关数据。如果您创建了一系列博客,每个博客都有相关的帖子,那么在使用内存数据时,将始终为每个博客加载相关的帖子。但是,当针对数据库运行时,只有使用Include方法才能加载数据。

因此,建议始终包含一定级别的端到端测试(除了单元测试之外),以确保应用程序在数据库中正常工作。

有一个名为Effort的工具,它适用于实体框架单元测试。也许值得一看,看看它是否符合您的要求?

从他们的主页:

它基本上是一个ADO.NET提供程序,它在轻量级进程内主存数据库上执行所有数据操作,而不是传统的外部数据库

最新更新