Skip to content

Instantly share code, notes, and snippets.

@badcommandorfilename
Created January 13, 2017 01:47
Show Gist options
  • Save badcommandorfilename/89af59bf1a69bf15766846c5263de131 to your computer and use it in GitHub Desktop.
Save badcommandorfilename/89af59bf1a69bf15766846c5263de131 to your computer and use it in GitHub Desktop.
Test utility to generate a an empty DbContext
internal class FakeContext
{
public static dynamic Cast(object obj, Type t)
{
if (obj is IConvertible)
{
return Convert.ChangeType(obj, t) as dynamic;
}
else
{
try
{
var param = Expression.Parameter(typeof(object));
return Expression.Lambda(Expression.Convert(param, t), param)
.Compile().DynamicInvoke(obj) as dynamic;
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
}
}
public static Mock<C> EmptyFakeContext<C>() where C : class
{
var mock = new Mock<C>();
var type = typeof(C);
var propertytypes = type.GetProperties().Select(x => x.PropertyType);
foreach (var p in propertytypes.Where(x => x.IsConstructedGenericType && x.Name.Contains("IDbSet")))
{
var innertype = p.GetGenericArguments().First();
EmptyFakeSet(mock, innertype);
}
return mock;
}
public static void EmptyFakeSet<C>(Mock<C> context, Type type) where C : class
{
var unbound = typeof(FakeDbSet<>);
var bound = unbound.MakeGenericType(type);
var iface = typeof(IDbSet<>).MakeGenericType(type);
var fakeset = Cast(Activator.CreateInstance(bound), iface);
var mi = context.GetType().GetMethods().Where(x => x.Name == "SetReturnsDefault").First();
var boundmethod = mi.MakeGenericMethod(iface);
boundmethod.Invoke(context, new[] { fakeset });
}
}
internal class FakeDbSet<T>
: IDbSet<T> where T : class
{
readonly HashSet<T> _data;
readonly IQueryable _query;
public FakeDbSet()
{
_data = new HashSet<T>();
_query = _data.AsQueryable();
}
public virtual T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public T Add(T item)
{
_data.Add(item);
return item;
}
public T Remove(T item)
{
_data.Remove(item);
return item;
}
public T Attach(T item)
{
_data.Add(item);
return item;
}
public void Detach(T item)
{
_data.Remove(item);
}
Type IQueryable.ElementType
{
get { return _query.ElementType; }
}
Expression IQueryable.Expression
{
get { return _query.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _query.Provider; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public T Create()
{
return Activator.CreateInstance<T>();
}
public ObservableCollection<T> Local
{
get
{
return new ObservableCollection<T>(_data);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment