我有一个接口方法,其签名如下:
void SetValues(IDictionary<string, object> the_values);
我有一个使用该方法的客户端类。我希望该类的单元测试验证,在特定情况下,传入特定的键和值对。现在,如果我想表达我期望调用SetValues
方法使用单键值对{“Date”,DateTime(1972,1,2)}我写下以下内容:
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))));
期望似乎有效,但我看起来很难看。是否有更好的方式来表达对作为参数传递的集合内容的期望?
答案 0 :(得分:1)
很可能没有。我同意这是丑陋的边界线。但更重要的是,它会产生难以理解的异常消息,如下所示:
IInterface.SetValues(items =&gt; items.Count()== 1&amp;&amp; items.First()。Key ==“Date”&amp;&amp; (DateTime)items.First()。Value == new DateTime(1972,1,2));预期#1,实际#0。
是的,你会知道失败了。在2周时间内不是非常有用的信息。说实话,当发生这种情况时,你很可能必须调试它才能知道发生了什么。相反,我建议这样做:
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");
// ...
});
或者,将验证完全放入其自己的方法中:
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;
});
}
答案 1 :(得分:0)
对于字典中小的固定数量的expecte项目,我认为Count
和特定条目的简单检查足够表达。如果值错误,测试将失败...
items.Count() == 1 && items["Date"]== new DateTime(1972,1,2);
您还可以使用Comparing two collections for equality irrespective of the order of items in them中涵盖的集合比较。