如何创建ObjectQuery来测试EF4'Include'方法

时间:2011-08-18 14:22:12

标签: entity-framework-4 typemock-isolator

我们正在使用EF4并为DAL层创建测试用例(DAL层具有linq查询)。我们使用TypeMock作为模拟框架。为了进行测试,我们创建了ObjectContext的Fakecontext和模拟CreateObjectSet方法,如下所示:

Isolate.WhenCalled(() => fakeContext.Context.CreateObjectSet<User>)).WillReturnCollectionValuesOf(fakeUsers.AsQueryable()); 

以上工作正常。问题是我们尝试使用“包含”来包含相关表格。我们扩展了include方法如下:

public static IQueryable<T> Include<T>(this IQueryable<T> source, Expression<Func<T>> property)
{ 
    var objectQuery = source as ObjectQuery<T>; 

    if (objectQuery != null) 
    { 
        var propertyPath = GetPropertyPath(property); 
        return objectQuery.Include(propertyPath); 
    } 

    return source; 
}

所以会发生什么,在上面的Include方法中,源类型应该是ObjectQuery<T>。但是,正如我们嘲笑CreateObjectSet一样,Include方法中的源类型属于Collection.Generic.List类型。请告诉我们如何在上述案例中嘲笑。您的及时帮助将非常值得一提。感谢

1 个答案:

答案 0 :(得分:0)

编写单元测试时,

Object Services可能很难使用。不幸的是,正如您所发现的那样,ObjectQuery<T>没有很好的模拟界面。为了处理这种情况,我在Repository模式之后创建了一个包装类来封装我的ObjectContext并创建了一个包装类来封装ObjectQuery<T>

public interface IMyObjectQuery<T> : IOrderedQueryable<T>
{
    IMyObjectQuery<T> Include(string path);
}

public class MyObjectQuery<T> : IMyObjectQuery<T>
{
    private ObjectQuery<T> _query;

    public MyObjectQuery(ObjectQuery<T> query)
    {
        _query = query;
    }

    IMyObjectQuery<T> Include(string path)
    {
        //There is probably a better way to do this
        //but you get the idea
        return new MyObjectQuery(_query.Include(path));
    }

    //Implement IQueryable, IEnumerable...
}

然后是为ObjectContext实现Repository包装器的问题。 Here是一个帮助您入门的链接。

添加如下内容:

public class MyRepository : IMyRespository
{
    ...
    public IMyObjectQuery<T> CreateQuery<T>()
    {
        return new MyObjectQuery(_context.CreateQuery<T>());
    }
    ...
}

这可能不是您正在寻找的简单解决方案,因为它不是一项微不足道的任务。我想你会发现,如果你不这样做,你将继续在编写测试时遇到困难。