断言该值等于任何期望值集合

chi*_*oro 6 .net c# nunit fluent-interface assertions

NUnit 是否提供了一个约束来确定实际值是否是给定的可枚举或数组的元素,换句话说,它等于多个预期值中的任何一个?就像是:

Assert.That(actual, Is.EqualToAnyOf(new[] { 1, 2, 3 }))
Run Code Online (Sandbox Code Playgroud)

也就是说,要指出的是,实际值是单个值。我希望值是1, 2, 或3。断言

Assert.That(actual, Contains.Element(expected))
Run Code Online (Sandbox Code Playgroud)

检查逻辑上相同,但意图相反:这里我们有一个实际值的集合,并期望其中有一个值。

此外,我发现了这些,但它们都不适合:

Assert.That(actual, Is.EqualTo(expected)) // only allows one value
Assert.That(actual, Is.InRange(start, end)) // only works for consecutive numbers
Assert.That(actual, Is.SubsetOf(expected)) // only works if actual is an enumerable
Assert.That(expected.Contains(actual)) // meaningless "expected: true but was: false" message
Run Code Online (Sandbox Code Playgroud)

Mic*_*ala 5

如果我没有忽略某些内容,CollectionAssert应该是您所需要的。它很简单:

CollectionAssert.Contains(IEnumerable expected, object actual);
Run Code Online (Sandbox Code Playgroud)

但是,似乎有多种方法可以实现您的目标,例如:

[Test]
public void CollectionContains()
{
    var expected = new List<int> { 0, 1, 2, 3, 5 };
    var actual = 5;

    CollectionAssert.Contains(expected, actual);
    Assert.That(expected, Contains.Item(actual));
}
Run Code Online (Sandbox Code Playgroud)

上述断言基本上应该断言相同并且可以互换使用。

编辑: 问题已修改,指出Assert.That(expected, Contains.Item(actual));即使它在逻辑上测试了相同的事物,也是无效的。


Pat*_*irk 2

我认为实现这一目标的唯一方法是创建自己的约束。不过做起来非常简单。

约束类本身:

public class OneOfValuesConstraint : EqualConstraint
{
    readonly ICollection expected;
    NUnitEqualityComparer comparer = new NUnitEqualityComparer();

    public OneOfValuesConstraint(ICollection expected)
        : base(expected)
    {
        this.expected = expected;
    }

    public override bool Matches(object actual)
    {
        // set the base class value so it appears in the error message
        this.actual = actual;
        Tolerance tolerance = Tolerance.Empty;

        // Loop through the expected values and return true on first match
        foreach (object value in expected)
            if (comparer.AreEqual(value, actual, ref tolerance))
                return true;

        // No matches, return false
        return false;
    }

    // Overridden for a cleaner error message (contributed by @chiccodoro)
    public override void WriteMessageTo(MessageWriter writer)
    {
        writer.DisplayDifferences(this);
    }

    public override void WriteDescriptionTo(MessageWriter writer)
    {
        writer.Write("either of ");
        writer.WriteExpectedValue(this.expected);
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使其流畅,创建一个静态方法来包装它(由 @chicodorro 贡献):

public static class IsEqual
{
    public static OneOfValuesConstraint ToAny(ICollection expected)
    {
        return new OneOfValuesConstraint(expected);
    }
}    
Run Code Online (Sandbox Code Playgroud)

然后使用它:

public static class IsEqual
{
    public static OneOfValuesConstraint ToAny(ICollection expected)
    {
        return new OneOfValuesConstraint(expected);
    }
}    
Run Code Online (Sandbox Code Playgroud)

失败并显示以下消息:

预期: < 0, 1, 2 > 之一

但是是:6