How to create ObjectQuery for testing EF4 'Include' method

656 Views Asked by At

We are using EF4 and creating test cases for DAL layer (DAL layer is having linq query). We are using TypeMock as mocking framework. For testing, we are creating Fakecontext of ObjectContext and mocking CreateObjectSet method as follows:

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

The above is working fine. The issue is when we are trying to include related tables using 'Include'. We have extended the include method as follows:

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; 
}

So what happen is, in the above Include method the source type should be ObjectQuery<T>. But as we have mocked CreateObjectSet, source type in Include method is of Collection.Generic.List type. Kindly let us know how should we mock in the above case. Your timely help will be highly appreciable. Thanks

1

There are 1 best solutions below

0
On

Object Services can be difficult to use when writing unit test. Unfortunately, there is not a good interface to mock for ObjectQuery<T> as you have found out. To handle this scenario I have created a wrapper class following the Repository pattern to encapsulate my ObjectContext and created a wrapper class to encapsulate 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...
}

And then it is a matter of implementing a Repository wrapper for your ObjectContext. Here is a link to get you started.

Add something like this:

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

This is probably not the simple solution that you were looking for, as it is not a trivial task. I think you will find that if you don't you will continue to encounter difficulty writing tests.