Search code examples
junitfloating-pointhamcrest

Does JUnit or Hamcrest have tolerance assertions?


I want to do an assertion where the actual value is within either a fixed +/- value of the expected value or a percent +/- value of the expected value.

While googling I noticed that NUnit had a nice syntax for that :

Assert.That( 5.5, Is.EqualTo( 5 ).Within(0.075);
Assert.That( 5.5, Is.EqualTo( 5 ).Within(1.5).Percent;

Does JUnit or Hamcrest have something similar I can use? If not, is there a nice way to express this behavior?


Solution

  • The short answer - yes.

    Old fashioned org.junit.Assert has a method assertEquals(java.lang.String message, float expected, float actual, float delta), and a bunch of a similar method for doubles, overloaded variants wihout the message, and similar implementations of assertArrayEquals.

    If you want to use Hamcrest, the closeTo matcher is what you're looking for.

    EDIT:
    To address the question in the comments about percentages - there isn't an out-of-box matcher for this, but you can gimmy-rig something yourself by dividing the two, and making sure they are between the desired ratio and its inverse. To take the example from the OP:

    float expected = 5.0;
    float actual = 5.5
    float ratio = 1.0075;
    float inverse = 1/ratio;
    
    float div = actual/expected;
    
    assertThat(div, allOf(greaterThan(inverse), lessThan(ratio)));
    

    It's a bit (well, a lot) clunky, but it should do the trick.