Moq'ing methods where Expression<Func<T, bool>> are passed in as parameters
Solution 1:
It is probably correct that only an Expression
with the exactly same structure (and literal values) will match. I suggest that you use the overload of Returns()
that lets you use the parameters the mock is called with:
repoMock.Setup(moq => moq.FindBy(It.IsAny<Expression<Func<Company, bool>>>())
.Returns((Expression<Func<Company, bool>> predicate) => ...);
In ...
, you can use predicate
to return the matching companies (and maybe even throw an exception if the matching companies isn't what you expected). Not very pretty, but I think it will work.
Solution 2:
You should be able to use It.IsAny<>()
to accomplish what you are looking to do. With the use of It.IsAny<>()
you can simply adjust the return type for your setup to test each branch of your code.
It.IsAny<Expression<Func<Company, bool>>>()
First Test, return a company regardless of predicate which will cause the exception to throw:
var repoMock = new Mock<IRepository<Company>>();
repoMock.Setup(moq => moq.FindBy(It.IsAny<Expression<Func<Company, bool>>>())).Returns(new List<Company>{new Company{Name = "Company Inc"}});
var signupLogic = new SignupLogic(repoMock.Object);
signupLogic.AddNewCompany(new Company {Name = "Company Inc"});
//Assert the exception was thrown.
Second Test, make the return type an empty list witch will cause add to be called.:
var repoMock = new Mock<IRepository<Company>>();
repoMock.Setup(moq => moq.FindBy(It.IsAny<Expression<Func<Company, bool>>>())).Returns(new List<Company>());
var signupLogic = new SignupLogic(repoMock.Object);
signupLogic.AddNewCompany(new Company {Name = "Company Inc"});
repoMock.Verify(r => r.Add(It.IsAny<Company>()), Times.Once());