Assuming that you just want to test the Service's Find
logic (and that you trust LINQ :-)), what you could do is just compile the incoming Expression
predicate and execute the expression across a fake repository (viz pred => fakePeople.Where(pred.Compile()));
):
[TestMethod]
public void TestMethod1()
{
var mock = new Mock<IRepository<Person>>();
var fakePeople = new[]
{
new Person {FirstName = "Justin", LastName = "Smith"},
new Person {FirstName = "Justin", LastName = "Quincy"},
new Person {FirstName = "Joe", LastName = "Bloggs"}
};
mock.Setup(r => r.Find(It.IsAny<Expression<Func<Person, bool>>>()))
.Returns<Expression<Func<Person, bool>>>(
pred => fakePeople.Where(pred.Compile()));
var personService = new PersonService(mock.Object);
var searchForJustins = personService.FindByName("Justin");
Assert.AreEqual(2, searchForJustins.Count());
Assert.IsTrue(searchForJustins.Any(_ => _.LastName == "Quincy")
&& searchForJustins.Any(_ => _.LastName == "Smith"));
var searchForEtheredges = personService.FindByName("Etheredge");
Assert.IsFalse(searchForEtheredges.Any());
}
Minor, but the Repository code itself didn't compile - I've assumed you have a generic repo pattern:
public interface IRepository<T>
{
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}
public class PersonService
{
readonly IRepository<Person> _repository;
public PersonService(IRepository<Person> repository)
{
_repository = repository;
}
public IEnumerable<Person> FindByName(string name)
{
return _repository.Find(p => p.FirstName.Equals(name));
}
}