Reputation: 584
I want to test method execution with anonymous parameter, but with known properties.
public interface IToTest
{
void MethodToTest(object data);
}
This is how I try to achieve this:
Mocker.Mock<IToTest>
.Verify(x=>x.MethodToTest(
It.Is<object>(
obj=>obj.Equals(new { DataProperty = "Test"})
)),
Times.Once());
Test is not passing.
I don't want to use
It.IsAny<object>()
because I know expected data.
Upvotes: 3
Views: 4818
Reputation: 4862
Your current delegate is testing that the whole object obj
is equal to the anonymous type object new { DataProperty = "Test"}
- which is unlikely to be testing what you want.
What you need to do is check that:
1) obj
has a property with the name you are expecting.
2) that property has a value that you are expecting.
Using reflection you can do both checks with something like the following:
Mocker.Mock<IToTest>
.Verify(x => x.MethodToTest(
It.Is<object>(
obj =>
obj.GetType().GetProperty("PropertyOne") != null &&
obj.GetType().GetProperty("PropertyOne").GetValue(obj).ToString() == "Test"
)),
Times.Once());
Important note - dont forget the NULL check on result of GetProperty()
for cases where the property does not exist.
Upvotes: 2
Reputation: 247153
You will need to use reflection within the delegate to make your comparisons, or use something like FluentAssertions
to offload the heavy lifting
for example
//...
var expected = new {
DataProperty = "Test"
//...known properties
};
Func<object, bool> match = _ => {
_.Should().BeEquivalentTo(expected);
return true;
};
Mocker.Mock<IToTest>
.Verify(x =>
x.MethodToTest(It.Is<object>(obj => match(obj))),
Times.Once());
Alternatively, you could have instead capture the object parameter in a callback and just assert the captured argument with fluent assertions.
Upvotes: 7