繁体   English   中英

Moq-模拟实体框架集

[英]Moq - mocking entity framework sets generically

我正在使用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

有什么方法可以使用反射或表达式根据类型在数据上下文中找到正确的集合对象,并将其设置为返回模拟集?

谢谢!

我认为在模拟第三方库的方法之前,我们需要看一下其源代码。

DbContext.Set调用InternalContext.Set ,请看一下源代码

    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 DbContext.Blogs

不要忘记,您仅嘲笑了Set方法,而不non-generic DBSet。 如果要使用模拟的内容,则应按以下方式使用它:

// context.Set<Blog>()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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