Does JUnit or Hamcrest have tolerance assertions?
Asked Answered
J

2

6

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?

Jaquelinejaquelyn answered 28/10, 2014 at 18:31 Comment(0)
C
9

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.

Claudioclaudius answered 28/10, 2014 at 18:44 Comment(3)
The closeTo matcher does compare two values with a fixed tolerance value. Isnt there something that also does percentage tolerances.Jaquelinejaquelyn
@algorithmic Unfortunately there isn't an easy, out-of-the-box way to do this, but see my edit for a solution.Claudioclaudius
the allOf, greaterThan and lessThan should do the trick provided I calculate the the percentage value of the expected value that I am expecting the tolerance to be in and use that. If I calculated the percentage value that I am willing to tolerate I guess I could also use closeTo. I am marking your answer since this is pretty much what I want.Jaquelinejaquelyn
I
4

Complementing Mureinik's answer:

To assert with a relative tolerance / percentage, you can just multiply:

    double closeTo5 = 4.6;
    double relativeTolerance = 0.1;
    double expected = 5;

    assertThat(closeTo5, 
        is(closeTo(expected, expected*relativeTolerance)));

Or, if you want to get fancy, write your own matcher (which is not hard)...

Isogloss answered 4/2, 2016 at 10:2 Comment(1)
I think the call to "is()" can be omitted, although some might find it more readable that way.Supplicate

© 2022 - 2024 — McMap. All rights reserved.