Using Moq .GetMock to register ~1IRepository with Linq Expression?
Is it possible to Mock a Linq Expression via Moq using a Generic class such as ~1Repository. ~IRepository being something that is injected via an IoC such as StructureMap or Windsor?
CODE TO TEST:
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();
EXCEPTION:
System.ArgumentException: Invalid setup on a non-member method:i => i.Find().Where(p => p.Id == "Fred").SingleOrDefault()
SOLUTION
using System.Linq;
...
_container.GetMock<IRepository>.Setup(i => i.Find<Person>())
.Returns(new List{person}.AsQueryable()).Verifiable();
开发者_高级运维
...
If Find<T>()
is an extension method on IRepository
, then I don't think it'll work, because you're dealing with a static
type.
If Find<T>()
is a method on IRepository
, then you set up a return value only for repository.Find<Person>()
.
Create an IEnumerable<>
or IQueryable<>
for Find<>()
to return (whichever type it is actually supposed to return -- I don't know which it is), and the LINQ expression will just do its work on that in the actual class. You don't have to mock the LINQ because that is just filtering the results of your own method, even though in production, if this is, say, Entity Framework or LINQ to SQL, the whole expression will instead be converted to an optimized database call.
If in your setup you give the collection an item with a matching ID, you'll assert that you get it back.
If in your setup you don't give the collection an item with a matching ID, you'll assert that you get null
(the default).
If in your setup you return null
from repository.Find<>()
, you'll assert than an exception is thrown because you can't call the extension methods on null
.
精彩评论