Использование Moq. GetMock для регистрации ~ 1IRepository с выражением Linq? - PullRequest
2 голосов
/ 28 января 2010

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

КОД ДЛЯ ИСПЫТАНИЯ:

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

TEST:

    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 (). Где (p => p.Id == "Fred"). SingleOrDefault ()

РЕШЕНИЕ

    using System.Linq;
    ...

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

    ...

1 Ответ

3 голосов
/ 28 января 2010

Если 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.

...