模拟实体框架存储库模式

时间:2016-05-04 11:15:21

标签: c# entity-framework moq

我的界面定义为:

 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,但是看不到如何仍然拥有包含的EF功能。我发现的大多数例子都是嘲笑一个简单的GetById。基本上我不想嘲笑EF,只是让它从内存而不是从Db读取。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:1)

在研究了这一点后,我意识到我想要做的事情是不可能的。

我想要的是用内存存储模拟数据库,然后测试我的查询是否有效,包括public class User { @SerializedName(value="username", alternate={"userId", "useriD"}) private String username ; ... } 方法(例如,有一些测试包括相关实体和一些不包含) 。我并不想模仿Include我实际上希望它能够像我的内存列表一样实现。这不可能来自以下here

  

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

     

出于这个原因,建议总是包含一些级别的   端到端测试(除了您的单元测试)以确保您的   应用程序对数据库正常工作。

答案 1 :(得分:0)

有一个名为Effort的工具,它适用于Entity Framework单元测试。可能值得一看,看它是否符合您的要求?

从他们的主页:

  

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