'How to assert an actual value against 2 or more expected values?

I'm testing a method to see if it returns the correct string. This string is made up of a lot of lines whose order might change, thus usually giving 2 possible combinations. That order is not important for my application.

However, because the order of the lines might change, writing just an Assert statement will not work, since sometimes it will pass the test, and sometimes it will fail the test.

So, is it possible to write a test that will assert an actual string value against 2 or more expected string values and see if it is equal to any of them?



Solution 1:[1]

Using the Hamcrest CoreMatcher (included in JUnit 4.4 and later) and assertThat():

assertThat(myString, anyOf(is("value1"), is("value2")));

Solution 2:[2]

I would use AssertJ for this:

import static org.assertj.core.api.Assertions.*;

assertThat("hello").isIn("hello", "world");

It's more concise and it will give you a descriptive message when the assertion fails.

Solution 3:[3]

I am using the following, I hope this would help:

String expectedTitles[] = {"Expected1","Expected2"};
List<String> expectedTitlesList = Arrays.asList(expectedTitles);

assertTrue(expectedTitlesList.contains((actualTitle)));

Solution 4:[4]

You can use Hamcrest for this:

assertThat(testString, anyOf(
    containsString("My first string"), 
    containsString("My other string")));

(I see Joachim just answered very similarly (+1)... i'll add this as another example.)

Solution 5:[5]

If your using junit I'd just do something like the following:

assertTrue(myString.equals("Value1") || myString.equals("Value"));

Solution 6:[6]

I read all answers, but the one that seems most compact and expressive to me is using Hamcrest's isOneOf which is already included in JUnit

assertThat(result, isOneOf("value1", "value2"));

which gives you a nice error message when failing.

java.lang.AssertionError: 
Expected: one of {"value1", "value2"}
     but: was "value"
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
[...]

Solution 7:[7]

Consider writing a custom hamcrest matcher returned by a method, in this case containsOneOf, i.e.:

assertThat(myString, containsOneOf("value1", "value2"));

In keeping with the "xUnit patterns" you should avoid conditional logic in your matcher, a loop with a break statement should suffice.

Have a look at Hamcrest and xUnit Patterns for more information.

Solution 8:[8]

If the content for a line is fixed you can split it at line endings before comparing. Then simply compare each line to a set of expected values. Something like this:

   Set<String> expectedValues = ...
   String[] split = text.split("\n");
   for(String str : split) {
      assert(expectedValues.contains(str));
   }

If you want to check that all expected values are present you can assert that expectedValue.remove(str) == true and assert after the loop that the Set is empty. If some lines may occur multiple times you have to use a Bag instead of a Set.

Solution 9:[9]

The simplest/most efficient might be

assert str.equals(result1) || str.equals(result2);

This will effectively have no overhead when you don't have assertions turned on.

Solution 10:[10]

Assuming the method under test returns an array, you could test using Hamcrest's arrayContainingInAnyOrder.

assertThat(result, is(arrayContainingInAnyOrder("value1", "value2", "value")))

Note: use of is wrapper is purely optional, used only as readability sugar.

Solution 11:[11]

I think you can just use assertTrue:

assertTrue(testString.matches("string1|string2"));

Solution 12:[12]

This seems to me like the simplest solution ...

assert obtainedValue in [acceptedValue1, acceptedValue2]

Solution 13:[13]

Simple solution using AssertTrue.
Just create a List.of() the expected values and check is it contains the expected value.

assertTrue(List.of("expected_1", "expected_2").contains("actual))

Solution 14:[14]

If you do not have or can't use third-party libraries except junit core, you can use this small helper method:

public static void assertListContains(List<Object> expected, Object actual) {
    if (!expected.contains(actual)) {
        fail("Expected: " + expected + " Actual: " + actual);
    }
}

Advantage, in contrast to other workaround answers, is that you can see what was expected and what was actual:

org.opentest4j.AssertionFailedError: Expected: [1, 2] Actual: 3

Solution 15:[15]

It's an old post, but I wanted to have an native easy answer, without having extra libraries to add. :)

So I did :

String e
e = "ear"
j = "jars"

assert (j == "jar" || e == "ear")

or if you want them to be both true

assert (j == "jar" && e == "ear")