Does NUnit provide a constraint to find whether the actual value is the element of a given enumerable or array, in other words, that it is equal to any of multiple expected values? Something like:
Assert.That(actual, Is.EqualToAnyOf(new[] { 1, 2, 3 }))
That is, to point out, the actual is a single value. I expect the value to be either 1
, 2
, or 3
. The assertion
Assert.That(actual, Contains.Element(expected))
checks logically the same, but it is the opposite intention: Here we have a collection of actual values and expect one value to be in it.
Furthermore, I found these but they all don't fit:
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
The assert. equal() method tests if two values are equal, using the == operator. If the two values are not equal, an assertion failure is being caused, and the program is terminated. To compare the values using the === operator, use the assert.
Method 1: using == operator Double equals operator is used to compare two or more than two objects, If they are referring to the same object then return true, otherwise return false. String is immutable in java. When two or more objects are created without new keyword, then both object refer same value.
Asserts that a condition is true. If the condition is false the method throws an AssertionException. That(Object, IResolveConstraint) Apply a constraint to an actual value, succeeding if the constraint is satisfied and throwing an assertion exception on failure.
CollectionAssert should be what you need if I am not overlooking something. It is as simple as:
CollectionAssert.Contains(IEnumerable expected, object actual);
However, there seems to be several ways to achieve your goal, such as:
[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));
}
Above assertions should basically assert the same and could be used interchangeably.
Edit:
Question was modified, stating that Assert.That(expected, Contains.Item(actual));
is not valid even though it logically tests the same thing.
There is a way to do this built in to NUnit, using the Or
constraint:
Assert.That(actual, Is.EqualTo(1).Or.EqualTo(2).Or.EqualTo(3))
If your list is more dynamic, you can build your list of Or
s like this:
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);
That latter answer doesn't read as well in the fluid syntax, but does achieve the dynamic building of or constraints. You could probably wrap that in a custom constraint as patrick-quirk demonstrated in order to achieve a more readbale fluid syntax, but that's up to you.
I know this is an old question, bu I have a maybe better (and native) suggestion. With NUnit 3.x (I'm on 3.10.1) you can use Is.AnyOf:
Assert.That(
actualValue,
Is.AnyOf(expectedValue1, expectedValue2, expectedValue3),
"My error message");
The only way I could see to accomplish this is by creating your own constraint. It's pretty straightforward to do though.
The constraint class itself:
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);
}
}
And to make it fluent, create a static method to wrap it (contributed by @chicodorro):
public static class IsEqual
{
public static OneOfValuesConstraint ToAny(ICollection expected)
{
return new OneOfValuesConstraint(expected);
}
}
Then to use it:
int[] expectedValues = new[] { 0, 1, 2 };
Assert.That(6, IsEqual.ToAny(expectedValues));
Fails with the message:
Expected: either of < 0, 1, 2 >
But was: 6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With