Использование Moq .GetMock для регистрации ~ 1IRepository с помощью Linq Expression?

Можно ли имитировать выражение Linq через Moq, используя универсальный класс, такой как ~ 1Repository. ~ IRepository вводится через IoC, например StructureMap или Windsor?

КОД ДЛЯ ПРОВЕРКИ:

   var person = _repository.Find<Person>()
                           .Where(p => p.Id == person.Id).SingleOrDefault();

ТЕСТ:

    var repository = new Mock<IRepository>();

    repository.Setup(i => i.Find<Person>()
                     .Where(p => p.Id == person.Id).SingleOrDefault())
                     .Returns(person).Verifiable();

ИСКЛЮЧЕНИЕ:

System.ArgumentException: неверная настройка метода, не являющегося членом: i => i.Find().Where(p => p.Id == "Fred").SingleOrDefault()

РЕШЕНИЕ

    using System.Linq;
    ...

    _container.GetMock<IRepository>.Setup(i => i.Find<Person>())
                     .Returns(new List{person}.AsQueryable()).Verifiable();

    ...

person Andrew    schedule 28.01.2010    source источник


Ответы (1)


Если Find<T>() является методом расширения для IRepository, то я не думаю, что он будет работать, потому что вы имеете дело с типом static.

Если Find<T>() является методом для IRepository, то вы устанавливаете возвращаемое значение только для repository.Find<Person>().

Создайте IEnumerable<> или IQueryable<> для возврата Find<>() (в зависимости от того, какой тип он на самом деле должен возвращать — я не знаю, какой именно), и выражение LINQ просто выполнит свою работу над этим в реальном классе. Вам не нужно имитировать LINQ, потому что это просто фильтрация результатов вашего собственного метода, даже если в производстве, если это, скажем, Entity Framework или LINQ to SQL, вместо этого все выражение будет преобразовано в оптимизированную базу данных. вызов.

Если в настройках вы передаете коллекции элемент с совпадающим идентификатором, вы утверждаете, что получите его обратно.
Если в настройках вы не даете коллекции элемент с совпадающим идентификатором, вы утверждаете, что что вы получаете null (по умолчанию).
Если в вашей настройке вы возвращаете null из repository.Find<>(), вы утверждаете, что возникает исключение, потому что вы не можете вызывать методы расширения для null.

person Jay    schedule 28.01.2010