I have an interface method whose signature is as follows:
void SetValues(IDictionary<string, object> the_values);
I have a client class that uses that method. I want The unit test for that class to verify that, in a particular case, a specific key and value pair are passed in. Right now, if I want to express that I'm expecting the SetValues
method to be called with the single key-value pair { "Date", DateTime(1972,1,2) } I write the following:
item.Expect(i => i.SetValues(
Arg<IDictionary<string, object>>.Matches(
(items) => (items.Count() == 1 &&
items.First().Key == "Date" &&
(DateTime) items.First().Value == new DateTime(1972,1,2))));
The expectation seems to work, but my does that look ugly. Is there a better way to express expectations about the contents of a collection being passed in as a parameter?
Most likely no. I agree this is border line ugly. But what's even more important, it produces undecipherable exception message, like this:
IInterface.SetValues(items => items.Count() == 1 && items.First().Key == "Date" && (DateTime) items.First().Value == new DateTime(1972,1,2)); Expected #1, Actual #0.
Yeah, you'll know it failed. Not very useful information in 2 weeks time. Truth to be told, when this happens you'll most likely have to debug it to get to know what's going on. Instead, I suggest doing this:
item.Expect(i => i.SetValues(Arg<IDictionary<string, object>>.Is.Anything))
.WhenCalled(invocation =>
{
var items = invocation.Arguments
.OfType<IDictionary<string, object>>()
.First();
Assert.That(items.Count(), Is.EqualTo(1));
Assert.That(items.First().Key, Is.EqualTo("Date");
// ...
});
Or, putting verification into it's own method altogether:
item.Expect(i => i.SetValues(IsCalledWithCorrectPair()));
// ...
private IDictionary<string, object> IsCalledWithCorrectPair()
{
return Arg<IDictionary<string, object>>.Matches(items =>
{
Assert.That(items.Count(), Is.EqualTo(1));
Assert.That(items.First().Key, Is.EqualTo("Date");
// ...
return true;
});
}