44

In my test case, I get an integer value:

int val = getXXX(); 

Then, I would like to check if val either equals to 3 or equals to 5 which is OK in either case. So, I did:

assertTrue(val == 3 || val==5); 

I run my test, the log shows val is 5, but my above assertion code failed with AssertionFailedError. Seems I can not use assertTrue(...) in this way, then, how to check true for OR condition?

1
  • 2
    Debug your test and inspect the value of val right before that assertTrue statement. Is it still 5? Commented Sep 25, 2013 at 12:16

6 Answers 6

64

You can use Hamcrest matchers to get a clearer error message here:

int i = 2; assertThat(i, Matchers.either(Matchers.is(3)).or(Matchers.is(5)) or int i = 2; assertThat(i, Matchers.anyOf(Matchers.is(3),Matchers.is(5))); 

This will more clearly explain:

Expected: (is <3> or is <5>) but: was <2> 

showing exactly the expectation and the incorrect value that was provided.

Sign up to request clarification or add additional context in comments.

2 Comments

For this to work one has to include a dependency on hamcrest-library. JUnit only depends on hamcrest-core, which does not include the Matchers class.
Tor those who don't have Matchers class in the Hamcrest library, you can use org.hamcrest.CoreMatchers instead. The example from the answer is than in this form: assertThat(i, CoreMatchers.either(CoreMatchers.is(3)).or(CoreMatchers.is(5))
30

ive tried to write quick test:

@Test public void testName() { int i = 5; junit.framework.Assert.assertTrue(i == 3 || i == 5); } 

its passing always so i guess there is some inbetween code when your value is changed. You can use

org.junit.Assert.assertEquals(5, i); 

to check value - this assertion will print out nice info whats wrong, for example:

java.lang.AssertionError: Expected :4 Actual :5 

Comments

7

While Harmcrest matchers can do the job, these constants can be easily refactored to a more meaninful constant, like a list of valid values. Then you can use the contains method to check that the value is present in the list - IMO is also easier to read:

public class Foo { public static final List<Integer> VALID_VALUES = Arrays.asList(3, 5); } @Test public void testName() { int i = 5; Assert.assertTrue(Foo.VALID_VALUES.contains(i)); } 

2 Comments

You would need to define a constant for each test case; I don't think this is reasonable beyond a couple of test cases. These constants will potentially be far from the place they're used. Another readability problem: Foo.VALID_VALUES.contains(i) is less clear than the approach with Harmcrest matchers. Harmcrest also provides a matcher with contains, which would also be much better than this.
The Hamcrest version is a lot better because it will print the observed value on failure. There is nothing more annoying than getting a test failure back from a long CI build which just says "false was not true".
2

In my case I wanted to do some complex assertion logic, so I simply implemented a method that returns a boolean and it did the job, the way it would be implemented in this example is as follows:

private Boolean is3or5(Integer val) { if(val == 3 || val == 5) { return true; } return false; } 

Then do the assertion:

assertTrue(is3or5(val)); 

Of course the method can contain more complex logic if needed

Comments

0

with TestNG this is also possible

Assert.assertTrue(val == 3 || val==5) 

Comments

0

This should do the OR conditional :

assertTrue("String does not match any expected values", "value1".equals(actualValue) || "value2".equals(actualValue)); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.