1

I'm looking to setup a fake repository.

public class FooRepo {

    public FutureFoo<Foo> GetById(int id) {

        var foo = new Foo();
        return new FutureValue(foo);
    }

    public FutureQuery<Foo> GetByCategory(int categoryId) {

        var foos = new[] { new Foo(), new Foo() new Foo() };

        return  //what goes here?
    }

}

The purpose of this is for writing data dependent tests while not depending on any database connectivity. This was really straightforward for the FutureValue<> type as it provides a constructor that accepts a direct object. However the constructor for FutureQuery<> takes the arguments IQueryable query, Action loadAction

Can i just ignore loadAction?

Such as: new FutureQuery<Foo>(foos.AsQueryable(), () => { });

Or what is the proper way to go about this?


Coerced solution:

(FutureQuery<Foo>) Activator.CreateInstance(typeof(FutureQuery<Foo>),
                   BindingFlags.NonPublic | BindingFlags.Instance, null, 
                   new object[] { foos.AsQueryable(), null }, null);
Chris Marisic
  • 32,487
  • 24
  • 164
  • 258

1 Answers1

1

Taken from FutureQueryBase.GetResult() :

    /// <summary>
    /// Gets the result by invoking the <see cref="LoadAction"/> if not already loaded.
    /// </summary>
    /// <returns>
    /// An <see cref="T:System.Collections.Generic.IEnumerable`1"/> that can be used to iterate through the collection.
    /// </returns>
    protected virtual IEnumerable<T> GetResult()
    {
        if (IsLoaded)
            return _result;

        // no load action, run query directly
        if (LoadAction == null)
        {
            _isLoaded = true;
            _result = _query as IEnumerable<T>;
            return _result;
        }

        // invoke the load action on the datacontext
        // result will be set with a callback to SetResult
        LoadAction.Invoke();
        return _result ?? Enumerable.Empty<T>();
    }

You should pass a null for the load action, unless you want to explicitly update _result through SetResult(ObjectContext, DbDataReader).

Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
  • 1
    Actually, if I understand the source correctly, the `loadAction` delegate is expected to call the `SetResult` method (which will in turn set the `_result` field that will be returned). So an empty action won't give the expected result (that is, returning the `IQueryable`). Setting `loadAction` to null seems safer – Kevin Gosse May 10 '16 at 21:30
  • @KooKiz Didn't even notice that part... I just went back and reread the code. Indeed, passing a `null` load action is the correct way of doing it, or else an empty sequence will be returned. – Xiaoy312 May 10 '16 at 21:50
  • @KooKiz I think you need subclass `FutureQueryBase`, the `FutureQuery` doesn't have a public .ctor. – Xiaoy312 May 10 '16 at 21:58
  • Passing in null worked fine. I never looked at the source of the base class after the digging i did in the repo i figured i was missing something. I originally didn't even notice the constructor was internal because i wasn't sure what i even wanted to pass in to it. – Chris Marisic May 11 '16 at 13:59