1

Я ищу, чтобы настроить поддельный репозиторий.Как подделать EntityFramework.Extended FutureQuery?

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

} 

Целью этого является запись тестов, зависящих от данных, в то время как они не зависят от подключения к базе данных. Это было очень просто для типа FutureValue<>, поскольку он предоставляет конструктор, который принимает прямой объект. Однако конструктор для FutureQuery<> принимает аргументы IQueryable query, Action loadAction

Могу ли я просто игнорировать loadAction?

Такие, как: new FutureQuery<Foo>(foos.AsQueryable(),() => { });

Или что такое правильный способ пойти по этому поводу?


Охваченная решение:

(FutureQuery<Foo>) Activator.CreateInstance(typeof(FutureQuery<Foo>), 
        BindingFlags.NonPublic | BindingFlags.Instance, null, 
        new object[] { foos.AsQueryable(), null }, null); 

ответ

1

Взятые из 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>(); 
    } 

Вы должны пройти null для действия нагрузки, если вы не хотите явно обновить _result через SetResult(ObjectContext, DbDataReader).

+1

На самом деле, если я правильно понял источник, делегат 'loadAction' должен вызвать метод SetResult (который, в свою очередь, установит поле' _result', которое будет возвращено). Таким образом, пустое действие не даст ожидаемого результата (т. Е. Возвращает 'IQueryable'). Установка 'loadAction' на null кажется более безопасной –

+0

@KooKiz Даже не заметила эту часть ... Я только что вернулся и перечитал код. Действительно, передача «нулевой» нагрузки - это правильный способ ее выполнения, иначе пустая последовательность будет возвращена. – Xiaoy312

+0

@KooKiz Я думаю, вам нужен подкласс 'FutureQueryBase',' FutureQuery' не имеет публичного .ctor. – Xiaoy312