简体   繁体   中英

Mock Entity Framework with in Memory Test Double

So, I pretty much feel somewhat frustrated on Microsoft suggested tutorials - I believe there are contracts that being missed but i am surprised that nowhere clue to be found.

I am trying to implement in memory test double for a certain Entity Framework 5 implementation. I tried MSDN's tutorial on EF 6 and it works pretty much (and obviously data only persistent for a single context - cause DbSet only being referenced in given context). However, the tutorial that suggested by Microsoft for EF 5 and earlier , it simply doesn't cut to it. I bet missing some contracts cause I get "Cannot implicitly convert type ..FakeSomeModelDbSet to System.Data.Entity.DbSet" ! But don't know what should I put on the : (extend) part and what else i should override.

Basically, here is my base mock DbSet implementation:

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
}

And here's one of it's implementation that intended to replace the original DbSet :

class FakeSomeModelbSet : MockDbSet<SomeModel>
{
    protected override Guid _GetObjectKey(SomeModel entity)
    {
        return entity.SomeModelId;
    }
}

And here how I'm going to hook the entire things in a certain DbContext ..

class MockingContext:OriginContext
{
    public MockCpdContext()
    {
        base.SomeModel = new FakeSomeModelbSet ();
    }
}

Don't ask me to use Moq adding a library is a no go, as I'm not the person in charge just a lowly coding drone. If you ask me the implementation of the OriginContext, it was generated by Database-first approach.. so.. i can, but that won't be much of help.

To be honest, the clue lies on the difference on tutorial code ( public class FakeDbSet<T> : IDbSet<T> ) and the original DbSet implementation ( public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable, IInternalSetAdapter where TEntity : class ) signatures.. but dunno what to do.. really.

Well, i just realized that in Entity Framework 5 DbSet only have a single constructor with internal modifier . It is not possible to inherit DbSet itself directly, it is only possible through replacing the DbSet in DbContext with IDbSet that is only possible to edit by modifying the .Context.tt file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM