带有内存测试双倍的模拟实体框架
Posted
技术标签:
【中文标题】带有内存测试双倍的模拟实体框架【英文标题】:Mock Entity Framework with in Memory Test Double 【发布时间】:2017-04-19 09:05:16 【问题描述】:因此,我对 Microsoft 建议的教程感到有些沮丧 - 我相信有些合同被遗漏了,但我很惊讶没有找到任何线索。
我正在尝试为某个 Entity Framework 5 实现实现内存测试替身。我尝试了MSDN's tutorial on EF 6,它的工作原理非常好(显然数据只在单个上下文中持久存在 - 导致 DbSet 仅在给定上下文中被引用)。但是,微软 for EF 5 and earlier 建议的教程,它根本没有切入它。我打赌错过了一些合同,因为我得到 “无法将类型 ..FakeSomeModelDbSet 隐式转换为 System.Data.Entity.DbSet”!但不知道我应该在:
(扩展)部分放什么以及我应该覆盖什么。
基本上,这是我的基本模拟 DbSet 实现:
abstract class MockDbSet<T> : IDbSet<T> where T : class
#region Properties
protected ObservableCollection<T> _data;
protected IQueryable _query;
Type IQueryable.ElementType
get return this._query.ElementType;
System.Linq.Expressions.Expression IQueryable.Expression
get return this._query.Expression;
IQueryProvider IQueryable.Provider
get return this._query.Provider;
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
return _data.GetEnumerator();
IEnumerator<T> IEnumerable<T>.GetEnumerator()
return _data.GetEnumerator();
#endregion
#region Public Methods
public MockDbSet()
this._data = new ObservableCollection<T>();
this._query = _data.AsQueryable<T>();
public T Find(params object[] keyValues)
return this._data.Single(x => this._GetObjectKey(x) == (Guid)keyValues.Single());
public T Add(T entity)
this._data.Add(entity);
return entity;
public T Remove(T entity)
this._data.Remove(entity);
return entity;
public T Attach(T entity)
this._data.Add(entity);
return entity;
public T Detach(T entity)
this._data.Remove(entity);
return entity;
public T Create()
return Activator.CreateInstance<T>();
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
return Activator.CreateInstance<TDerivedEntity>();
public ObservableCollection<T> Local
get return this._data;
#endregion
#region Protected Methods
protected abstract Guid _GetObjectKey(T entity);
#endregion
这是其中一个旨在替换原始 DbSet
的实现:
class FakeSomeModelbSet : MockDbSet<SomeModel>
protected override Guid _GetObjectKey(SomeModel entity)
return entity.SomeModelId;
在这里,我将如何将整个事情挂钩到某个 DbContext
..
class MockingContext:OriginContext
public MockCpdContext()
base.SomeModel = new FakeSomeModelbSet ();
不要让我使用 Moq 添加库是不行的,因为我不是负责人,只是一个低级的编码无人机。如果你问我 OriginContext 的实现,它是由Database-first
方法生成的。所以.. 我可以,但这不会有太大帮助。
说实话,线索在于 教程代码 (public class FakeDbSet<T> : IDbSet<T>
) 和 原始 DbSet 实现 (public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable, IInternalSetAdapter where TEntity : class
) 签名的区别.. 但不知道怎么办..真的。
【问题讨论】:
【参考方案1】:好吧,我刚刚意识到在 Entity Framework 5 DbSet
中只有一个带有 internal 修饰符的构造函数。无法直接继承DbSet
本身,只能通过将DbContext
中的DbSet
替换为IDbSet
才能实现,只能通过修改.Context.tt
文件进行编辑。
【讨论】:
以上是关于带有内存测试双倍的模拟实体框架的主要内容,如果未能解决你的问题,请参考以下文章
在带有.Net Core的内存数据库中,不向实体集合添加数据