如何模拟 DbSet 的 Include 方法?

ash*_*ina 5 c# nunit unit-testing moq

我的存储库中有以下方法

public IQueryable<T> QueryWithInclude(String include)
        {
            return _dbSet.Include(include);
        }
Run Code Online (Sandbox Code Playgroud)

我如何模拟我正在使用 Moq 的这种方法。我似乎无法找到正确的方法。

例如,我可以执行以下操作

public IQueryable<T> Query()
            {
                return _dbSet;
            }

mockrepository.Setup(_ => _.Query()).Returns(foo.AsQueryable()); 
Run Code Online (Sandbox Code Playgroud)

此外,如果最终证明这种方法的模拟很困难,那么考虑替代实现/解决方法是否明智?

Qui*_*rdt 3

只要你的抽象返回IQueryable(比如DbSet),那么你就可以创建你自己的Include扩展IQueryable。您的代码将自动调用新的 Include 扩展方法。当用于返回 a 的抽象时DbQuery,它将调用正确的 Invoke,否则如果它是一个IQueryable实例,它将不执行任何操作。添加这个新的扩展方法意味着您当前的代码应该无需任何更改即可编译。

像这样:

    /// see: http://msdn.microsoft.com/en-us/library/ff714955.aspx
    ///     
    /// The method has been modified from version that appears in the referenced article to support DbContext in EF 4.1 ->
    /// 
    /// </summary>
    public static class ModelExtensions {
        public static IQueryable<T> Include<T>
                (this IQueryable<T> sequence, string path) where T : class {
            var dbQuery = sequence as DbQuery<T>;
            if (dbQuery != null) {
                return dbQuery.Include(path);
            }
            return sequence;
        }
    }
Run Code Online (Sandbox Code Playgroud)

因此,如果您的单元测试使用假IQueryable列表,则 Include 将不会执行任何操作。

我必须补充一点,对于为什么模拟 EntityFramework 是不好且毫无价值的,有很多强烈的观点。如果您还没有看到它们,那么检查一下可能是值得的。