我有一个定义为:的接口
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提供程序,它在轻量级进程内主存数据库上执行所有数据操作,而不是传统的外部数据库