带有内存测试双倍的模拟实体框架

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&lt;T&gt; : IDbSet&lt;T&gt;) 和 原始 DbSet 实现 (public class DbSet&lt;TEntity&gt; : DbQuery&lt;TEntity&gt;, IDbSet&lt;TEntity&gt;, IQueryable&lt;TEntity&gt;, IEnumerable&lt;TEntity&gt;, IQueryable, IEnumerable, IInternalSetAdapter where TEntity : class) 签名的区别.. 但不知道怎么办..真的。

【问题讨论】:

【参考方案1】:

好吧,我刚刚意识到在 Entity Framework 5 DbSet 中只有一个带有 internal 修饰符的构造函数。无法直接继承DbSet本身,只能通过将DbContext中的DbSet替换为IDbSet才能实现,只能通过修改.Context.tt文件进行编辑。

【讨论】:

以上是关于带有内存测试双倍的模拟实体框架的主要内容,如果未能解决你的问题,请参考以下文章

如何使用实体框架测试视图?

实体框架 4 的内存数据库

在带有.Net Core的内存数据库中,不向实体集合添加数据

我应该如何设置我的集成测试以使用带有实体框架的测试数据库?

带有 Autofac 单元测试 DataContext 的实体框架 6

如何启动内存数据库来测试 JPA 实体?