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

80,509

Solution 1

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

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

Solution 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

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

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

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)
[...]
Share:
80,509
Alex
Author by

Alex

www.micktagger.com and @shtopointo

Updated on July 09, 2022

Comments

  • Alex
    Alex almost 2 years

    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?

  • Alex
    Alex almost 13 years
    I managed to fix this eventually, but for some reason, for me, JUnit 4 doesn't have an 'assertThat' method in CoreMatcher. I ended up combining the main Hamcrest library with the JUnit library in order to get it to work.
  • Alex
    Alex almost 13 years
    Not for me...I just see assertTrue
  • Joachim Sauer
    Joachim Sauer almost 13 years
    @Andrei: are you sure you checked org.junit.Assert and not junit.framework.Assert? The later only exist for backwards compatibility with JUnit 3 and doesn't support assertThat. In org.junit.Assert` was introduced in JUnit 4.4. So if you have an earlier version, it will be missing.
  • likejudo
    likejudo over 7 years
    but in Android studio, I am finding that asserts are not evaluated in my instrumented tests. I need to use assertTrue instead
  • Vishy
    Vishy over 7 years
    @likejiujitsu you need to ensure -ea is a command line option. assertEquals is best for testing but only use assert in production so it can be turned off.
  • Extreme
    Extreme almost 7 years
    for who use junit Assert String expectedTitles[] = {"In-Progress","Completed"}; List<String> expectedTitlesList = Arrays.asList(expectedTitles); Assert.assertTrue(expectedTitlesList.contains((transferReque‌​st.getRequestStatus(‌​))));
  • Sanchit
    Sanchit about 6 years
    assert.assertequals(expected, actual) doesn't allow || operator
  • Vishy
    Vishy about 6 years
    @Sanchit assetTrue does.
  • Franz See
    Franz See about 6 years
    This is a bad practice in testing. Though logically, it will pass and fail when it's supposed to, the problem is that if it fails, you will not have a descriptive error message. instead, you will get something like "expected true but was false" which tells you nothing about the problem. But by using hamcrest matchers or assertj, you will get something like this on failure : expected to be one of the following : "Value1", "Value2" but was "XYZ"
  • Franz See
    Franz See about 6 years
    But this will not show you any meaningful error message when it fails. Using hamcrest or assertj provides you with something like "expected values X, Y but was Z"
  • Paulo Merson
    Paulo Merson over 5 years
    What import statement do you have for isOneOf? What JUnit version?
  • fglez
    fglez over 5 years
  • sergeyan
    sergeyan over 4 years
    For those who is forced to use junit 3 this is a good solution.
  • JiaHao Xu
    JiaHao Xu over 3 years
    You missed one ')' at the end of assertThat statement.
  • Joachim Sauer
    Joachim Sauer over 3 years
    @JiaHaoXu: indeed, fixed now. Note that you can edit (or suggest an edit) the answer yourself for typos like this.
  • Jacob van Lingen
    Jacob van Lingen about 3 years
    Deprecated: use is(oneOf(...)) instead.
  • user2081279
    user2081279 almost 3 years
    Please add the relevant import statements to the example, to make it more clear.
  • user2081279
    user2081279 almost 3 years
    Please add the relevant import statements to the example, to make it more clear.