Search code examples
javaunit-testingfloating-pointprecisionassertj

Java assertj double containsSequence


How do I specify the double/float tolerance to assertj while comparing a double sequence? Here, items is a List<ScoredItem> and ScoredItem has 2 attributes itemId and score.

assertThat(items).extracting("score").containsSequence(3.0, 2.0, 1.0, 0.35, 0.2);

This is throwing an exception during unit tests.

java.lang.AssertionError: 
Expecting:
 <[3.0, 2.0000000298023224, 1.0, 0.3500000052154064, 0.20000000298023224]>
to contain sequence:
 <[3.0, 2.0, 1.0, 0.35, 0.2]>

I also tried:

assertThat(items).extracting("score").containsSequence(new double[]{3.0, 2.0, 1.0, 0.35, 0.2}, Offset.offset(0.01));

...but no luck :(


Solution

  • Since this is extracted from a list, you have to call the generic method using usingComparatorForType before calling the containsSequence (Thanks to Joel who corrected my reversed sequence). Then you can pass in the DoubleComparator.

    assertThat(items)
       .extracting("score")
       .usingComparatorForType(new DoubleComparator(0.2), Double.class)
       .containsSequence(3.0, 2.0, 1.0, 0.35, 0.2);
    

    If items is just a double [], then you just need to call the method usingComparatorWithPrecision

    assertThat(items)
        .usingComparatorWithPrecision(0.5)
        .containsSequence(3.0, 2.0, 1.0, 0.35, 0.2);
    

    or replace the offset from the second line with withPrecision

    assertThat(items).extracting("score")
        .containsSequence(new double[]{3.0, 2.0, 1.0, 0.35, 0.2}, withPrecision(0.5));
    

    I've test this with AssertJ 3.9.1 using the following code:

    public class ScoredItem {
        public int itemId;
        public double score;
    
        public ScoredItem(int i, double s) {
            itemId = i;
            score = s;
        }
    
        public static void main(String[] args) {
            List<ScoredItem> items = new ArrayList<ScoredItem>();
            items.add(new ScoredItem(1,3.0));
            items.add(new ScoredItem(1,2.0));
            items.add(new ScoredItem(1,1.1));
            items.add(new ScoredItem(1,0.33));
            items.add(new ScoredItem(1,0.22));
    
            assertThat(items)
                .extracting("score")
                .usingComparatorForType(new DoubleComparator(0.2), Double.class)
                .containsSequence(3.0, 2.0, 1.0, 0.35, 0.2);
    
        }
    }