1

我有一个接口方法,其签名如下:

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))));

期望似乎奏效了,但我这样做看起来很难看。有没有更好的方法来表达对作为参数传入的集合内容的期望?

4

2 回答 2

1

很可能没有。我同意这是丑陋的边界线。但更重要的是,它会产生无法解读的异常消息,如下所示:

IInterface.SetValues(items => items.Count() == 1 && items.First().Key == "Date" && (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;
    });
}
于 2013-07-04T23:52:25.243 回答
0

对于字典中少量固定数量的预期项目,我认为简单的检查Count和特定条目就足够表达了。如果值错误,测试将失败...

 items.Count() == 1 && items["Date"]== new DateTime(1972,1,2);

您还可以使用比较两个集合的相等性中所述的集合比较,而不考虑其中项的顺序

于 2013-07-04T23:48:50.980 回答