如何在JUnit中比较两个double列表

Fra*_*ois 9 java junit hamcrest

在JUnit 4测试中,我有一个方法getValues()返回一个List<Double>我想要与引用列表进行比较的对象.到目前为止,我发现的最佳解决方案是使用org.hamcrest.collection.IsArray.hasItemsorg.hamcrest.Matchers.closeTo喜欢这样:

assertThat(getValues(), hasItems(closeTo(0.2, EPSILON), closeTo(0.3, EPSILON)));
Run Code Online (Sandbox Code Playgroud)

这适用于仅返回少量值的测试.但是如果测试返回更多值,这绝对不是最好的方法.

我也尝试了以下代码.要编译的代码需要向下转换为Matcherbefore hasItems:

List<Matcher<Double>> doubleMatcherList = new ArrayList<Matcher<Double>>();
doubleMatcherList.add(closeTo(0.2, EPSILON));
doubleMatcherList.add(closeTo(0.3, EPSILON));
assertThat(getValues(), (Matcher) hasItems(doubleMatcherList));
Run Code Online (Sandbox Code Playgroud)

比较失败,我不明白为什么:

java.lang.AssertionError:Expected :(一个包含<[数字值<1.0E-6> <0.2>的数字​​,<1.0> -0> <0.3>的数值>]>的集合得到:<[ 0.2,0.30000000000000004]>

是否有更好的方法来比较两个大型双打名单?这里的困难是需要数值公差来验证结果getValues()是否等于我的参考列表.对于任何对象列表,这种比较似乎都很容易,但对于列表却没有Double.

Mic*_*mlk 7

我认为这里正确的解决方案是自定义匹配器.基本上类似于IsIterableContainingInOrder,它只适用于双打并支持错误边距.


use*_*389 5

如果您愿意从转换List<Double>double[],则assertArrayEquals允许指定错误容差:

assertArrayEquals(new double[] {1, 2}, new double[] {1.01, 2.09}, 1E-1);
Run Code Online (Sandbox Code Playgroud)

Java 8中,从列表到数组的转换是相对干净的(请参阅相关问题)。例如:

double[] toArray(List<Double> list) {
    return list.stream().mapToDouble(Number::doubleValue).toArray();
}
Run Code Online (Sandbox Code Playgroud)

然后assert语句可以如下:

assertArrayEquals(toArray(refList), toArray(getValues()), 1E-9);
Run Code Online (Sandbox Code Playgroud)

只需将签名更改为,toArray就可以使ps 适用于任何Number类型double[] toArray(List<? extends Number> list)