Search code examples
c#lambdamicrosoft-fakes

Stub interface with generic methods that take predicates


I am really struggling with getting this to work. I have a generic repository pattern and I need to stub the repository interface using Microsoft Fakes.

public interface IDataAccess<T> where T : class
{
    void Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(Expression<Func<T, bool>> where);
    T FindById(long id);
    T FindById(string id);
    T Find(Expression<Func<T, bool>> where);
    IEnumerable<T> FindAll();
    IEnumerable<T> FindMany(Expression<Func<T, bool>> where);
    IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes);
    IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties);
}

trying to create a stub for

IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes);
IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties);

and in my test..

IDataAccess<EnterprisePermissionSet> dataAccess = new HG.Fus.Authentication.Data.Fakes.
            StubIDataAccess<EnterprisePermissionSet>()
        {
            FindIncludingExpressionOfFuncOfT0ObjectArray = () => { };
        };

I just have no clue how to construct this stub,


Solution

  • MsFakes uses code generation to replace to fake methods, create stubs and etc... To replace a particular method you have to set new method(Action or Func based on the method signature) which will receive any call to this particular method.

    The signature of the method you wish to fake is:

    IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties);
    

    Based on this signature you have to set a Func which gets an array of Expression<Func<T, object>> and returns IQueryable<T>. The following snippet shows a simple example to replace the above method:

    fakeDataAccess.FindIncludingExpressionOfFuncOfT0ObjectArray = expressions =>
    {
       // here you can create the logic / fill the return value and etc...
       return new List<EnterprisePermissionSet>().AsQueryable(); \\this example is match your T
    };
    

    The easiest way to simulate IQueryable<T> is to return a collection through AsQueryable(), another way is to use EnumerableQuery class.

    Here is the example to replace: IQueryable<T> Find(Expression<Func<T, bool>> predicate = null, params Expression<Func<T, object>>[] includes);

    fakeDataAccess.FindExpressionOfFuncOfT0BooleanExpressionOfFuncOfT0ObjectArray =
    (expression, expressions) =>
         {
              // here you can create the logic / fill the return value and etc...
              return new List<EnterprisePermissionSet>().AsQueryable();
         };