I have a fallowing method in my Repository class:
public virtual IEnumerable<T> GetAll(Expression<Func<T, bool>> where = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, Expression<Func<T, object>>[] includeProperties = null)
I would like to ask You, how it can be mocked to return some specific value, when I am passing in some concrete lambda expression?
SettingsRepository.Setup(
r =>
r.GetAll(
It.IsAny<Expression<Func<Settings, bool>>>(),
It.IsAny<Func<IQueryable<Settings>, IOrderedQueryable<Settings>>>(),
It.IsAny<Expression<Func<Settings, Object>>[]>())).Returns((Settings[])null);
This will return null, no matter what lambda you will use.
I am looking for something like that:
Expression<Func<Settings, bool>> asdasd = s => s.SubmissionId==1;
SettingsRepository.Setup(
r =>
r.GetAll(
It.Is<Expression<Func<Settings, bool>>>(asdasd),
It.IsAny<Func<IQueryable<Settings>, IOrderedQueryable<Settings>>>(),
It.IsAny<Expression<Func<Settings, Object>>[]>()))
.Returns(() => new[] { new Settings { Submission = ValidSubmission } });
Best regards, Angel
Edit: Thank you for the answers! Ilya Palkin, you are absolutely right! It should be something like this:
It.Is<Expression<Func<Settings,bool>>>(ex=>ex == null)
"ex" points to expression, that I'm supposed to pass as an argument, right? And the lambda expression is delegate from the type that you predicted. Now it's working!
SettingsRepository.Setup(
r =>
r.GetAll(
It.Is<Expression<Func<Settings,bool>>>(ex=>ex == null),
It.IsAny<Func<IQueryable<Settings>, IOrderedQueryable<Settings>>>(),
It.IsAny<Expression<Func<Settings, Object>>[]>()))
.Returns(() =>
{
ValidSettings.Submission = ValidSubmission;
return new[] { ValidSettings };
});
SettingsRepository.Setup(
r =>
r.GetAll(
It.Is<Expression<Func<Settings, bool>>>(ex => ex != null),
It.IsAny<Func<IQueryable<Settings>, IOrderedQueryable<Settings>>>(),
It.IsAny<Expression<Func<Settings, Object>>[]>())).Returns(new Settings[0]);
Now, on invocation, the method will return different things accordingly to the value of arguments in use.
I'm going back to the theme with another related question, that arise today among my colleagues and here it is:
Like example above, we have stubbed SettingsRepository object;
Is it possible to setup a mock object on that way, so if you pass one very specific lambda to return some predefined collection, otherwise empty collection;
e.g. If I say: SettingsRepository.Object.GetAll(x=>x.Id==3,...,...)
-> I want to obtain predefined collection and if I say: SettingsRepository.Object.GetAll(x=>x.Id==4,...,...)
-> empty collection. It is easy feasible with simple types like int and string, but with expressions??
You can control reactions of the mock by passing lambda on the It.Is() or It.IsAny() methods.
It.Is<Expression<Func<Settings,bool>>>(x=>*what to do with "x"*)
, "x" points to Expression<Func<...>>
and now I have to specify the condition, but what it should be?
If I was using int I would do it like this:
mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);
It.Is<Expression<Func<Settings,bool>>>(ex=>ex == null)
you can simply usenull
, that is just use the simple valuenull
as the first argument toGetAll
inside yourSetup
. – Unstrung