How to fake DbContext.Entry method in Entity Framework with repository pattern

An example of how to implement Interface based repositories and unit of work to get what you are after:

public interface IRepository<T>
    {
        T FindSingle(Expression<Func<T, Boolean>> predicate, params Expression<Func<T, object>>[] includeExpressions);
        void ProxyGenerationOn();
        void ProxyGenerationOff();
        void Detach(T entity);
        void Add(T newEntity);
        void Modify(T entity);
        void Attach(T entity);
        void Remove(T entity);
        void SetCurrentValues(T modifiedEntity, T origEntity);
        T GetById(int id);
        T GetById(int id, bool sealOverride);
        IQueryable<T> GetAll();
        IQueryable<T> GetAll(bool sealOverride);
        IQueryable<T> GetAll(string[] EagerLoadPaths);
        IQueryable<T> Find(Expression<Func<T, Boolean>> predicate);
    }



public interface IUnitOfWork : IDisposable
    {
       //repository implementations go here
       bool SaveChanges()
     }

Notice how the context is completely abstracted away. You only need to worry about it in the concrete implementations.


To get around this I added a method overload, and added an obsolete attribute to see where the original method was being called.

    public virtual void Entry<TEntity>(TEntity entity, Action<DbEntityEntry<TEntity>> action) where TEntity : class
    {
        action(base.Entry(entity));
    }

    [Obsolete("Use overload for unit tests.")]
    public new DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class
    {
        return base.Entry(entity);

        /** or **/

        throw new ApplicationException("Use overload for unit tests.");
    }

then you can DbContext.Entry(order, ent => ent.State = EntityState.Modified;


Found the answer here by "adding additional level of indirection" we get:

public virtual void SetModified(object entity)
{
    Entry(entity).State = EntityState.Modified;
}

and use DbContext.SetModified(entity) in our controller. mockContext.Setup(c => c.SetModified(It.IsAny()));