我正在考虑使用Moq来模拟我的实体框架数据上下文,目前我正在使用EntityFramework.Testing库来提供帮助。我有以下代码:
var set = new Mock<DbSet<Blog>>().SetupData(data);
var context = new Mock<BloggingContext>();
context.Setup(c => c.Blogs).Returns(set.Object);但是,我想创建一个接受实体类型并自动设置它的泛型方法。所以类似于下面的内容
public void SetupData<T>(List<T> items) where T : class
{
var set = new Mock<DbSet<T>>().SetupData(items);
var context = new Mock<BloggingContext>();
context.Setup(c => c.Set<T>()).Returns(set.Object);
}然而,我模拟了泛型的'Set‘对象,数据上下文对象仍然是空的-即dataContext.Blogs
有没有什么方法可以使用反射或表达式来根据类型在数据上下文中找到正确的set对象,并将其设置为返回我的模拟set?
谢谢!
发布于 2019-05-25 20:28:58
我认为在模仿第三方库的方法之前,我们需要先看一下它的源代码。
DbContext.Set调用InternalContext.Set,请使用look on the source code
public virtual IInternalSetAdapter Set(Type entityType)
{
entityType = ObjectContextTypeCache.GetObjectType(entityType);
IInternalSetAdapter set;
if (!_nonGenericSets.TryGetValue(entityType, out set))
{
// We need to create a non-generic DbSet instance here, which is actually an instance of InternalDbSet<T>.
// The CreateInternalSet method does this and will wrap the new object either around an existing
// internal set if one can be found from the generic sets cache, or else will create a new one.
set = CreateInternalSet(
entityType, _genericSets.TryGetValue(entityType, out set) ? set.InternalSet : null);
_nonGenericSets.Add(entityType, set);
}
return set;
}正如您所看到的,它试图从私有字典_nonGenericSets中查找值,我认为这就是当您直接从DbContext.Blogs获取值时,它返回null的原因。
不要忘记,您只模拟了Set方法,而没有模拟non-generic DBSets。如果你要使用你模拟过的东西,你应该像下面这样使用它:
// context.Set<Blog>()https://stackoverflow.com/questions/56303957
复制相似问题