NUnit是否提供约束来查找实际值是否是给定枚举或数组的元素,换句话说,它是否等于多个预期值中的任何一个?类似的东西:
Assert.That(actual, Is.EqualToAnyOf(new[] { 1, 2, 3 }))
也就是说,要指出的是,实际是单个值。我希望该值可以是1
,2
或3
。断言
Assert.That(actual, Contains.Element(expected))
逻辑上检查相同,但这是相反的意图:这里我们有一组实际值,并期望有一个值。
此外,我发现了这些,但它们都不合适:
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
答案 0 :(得分:4)
CollectionAssert应该是你需要的。它很简单:
CollectionAssert.Contains(IEnumerable expected, object actual);
但是,似乎有几种方法可以实现您的目标,例如:
[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));
}
以上断言应该基本断言相同,并且可以互换使用。
修改强>
问题被修改,说明Assert.That(expected, Contains.Item(actual));
无效,即使它在逻辑上测试相同的东西。
答案 1 :(得分:2)
有一种方法可以使用Or
约束来内置NUnit:
Assert.That(actual, Is.EqualTo(1).Or.EqualTo(2).Or.EqualTo(3))
如果您的列表更具动态性,您可以构建Or
的列表,如下所示:
var expected = new[] { 1, 2, 3 };
var constraints = Is.EqualTo(expected[0]);
for(var i = 1; i < expected.Length; i++)
constraints = constraints.Or.EqualTo(expected[i]);
Assert.That(actual, constraints);
后面的答案在流畅的语法中并没有读取,但确实实现了动态构建或约束。您可以将其作为patrick-quirk演示的自定义约束包装,以实现更多的readbale流体语法,但这取决于您。
答案 2 :(得分:1)
我能看到实现这一目标的唯一方法是创建自己的约束。尽管如此,这很简单。
约束类本身:
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);
}
}
为了使它流畅,创建一个静态方法来包装它(由@chicodorro提供):
public static class IsEqual
{
public static OneOfValuesConstraint ToAny(ICollection expected)
{
return new OneOfValuesConstraint(expected);
}
}
然后使用它:
int[] expectedValues = new[] { 0, 1, 2 };
Assert.That(6, IsEqual.ToAny(expectedValues));
信息失败:
预期:&lt; 0,1,2&gt;
但是:6
答案 3 :(得分:0)
我知道这是一个古老的问题,但是我有一个更好的(和本地的)建议。 使用NUnit 3.x(我在3.10.1上),您可以使用 Is.AnyOf :
Assert.That(
actualValue,
Is.AnyOf(expectedValue1, expectedValue2, expectedValue3),
"My error message");