首页 > 解决方案 > Java assertj double containsSequence

问题描述

如何在比较双序列时为 assertj 指定双精度/浮点容差?这里,items是 aList<ScoredItem>并且ScoredItem有 2 个属性itemIdscore

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

这在单元测试期间引发异常。

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]>

我也试过:

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

...但没有运气:(

标签: javaunit-testingfloating-pointprecisionassertj

解决方案


由于这是从列表中提取的,因此您必须在调用usingComparatorForType之前调用泛型方法 using containsSequence(感谢乔尔纠正了我的逆序)。然后就可以传入了DoubleComparator

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

如果items只是 a double [],那么您只需要调用该方法usingComparatorWithPrecision

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

或将offset第二行中的替换为withPrecision

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

我使用以下代码使用 AssertJ 3.9.1 对此进行了测试:

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);

    }
}

推荐阅读