How to mock a method call that takes a dynamic object
Moq provided It.IsAny<T>
for that case
sessionMock.Setup(x => x.Get<User>(It.IsAny<object>()).Returns(new User());
*dynamic is any object
First of all, anonymous objects are not really dynamic
.
If you used dynamic
objects like
dynamic user1Filter = new ExpandoObject();
user1Filter.Name = "test 1";
var user1 = session.Get<User>(user1Filter);
you could mock it like
sessionMock.Setup(x => x.Get<User>(DynamicFilter.HasName("test 1")));
by implementing custom argument matcher:
static class DynamicFilter
{
[Matcher] public static object HasName(string name) { return null; }
public static bool HasName(dynamic filter, string name)
{
string passedName = filter.Name; //dynamic expression
return name.Equals(passedName);
}
}
You can use the It.Is<object>
matcher together with reflection. You cannot use dynamic in expression trees so It.Is<dynamic>
won't work that's why you need reflection to get the your property value by name:
sessionMock
.Setup(x => x.Get<User>(
It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 1")))
.Returns(new User{Id = 1});
sessionMock
.Setup(x => x.Get<User>(
It.Is<object>(d => d.GetPropertyValue<string>("Name") == "test 2")))
.Returns(new User { Id = 2 });
Where GetPropertyValue
is a little helper:
public static class ReflectionExtensions
{
public static T GetPropertyValue<T>(this object obj, string propertyName)
{
return (T) obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}
}