assertEquals(Double,Double)和assertEquals(double,double,delta)之间的Junit差异

Jam*_*mas 11 java junit unit-testing

我有一个junit测试断言两个Double对象具有以下内容:

Assert.assertEquals(Double expected, Double result);
Run Code Online (Sandbox Code Playgroud)

这很好,然后我决定改变它以使用原始的双倍,结果被弃用,除非你也提供了一个delta.

所以我想知道在这个assertEquals中使用Double对象或原始类型有什么区别?为什么在没有delta确定的情况下使用对象,但是不推荐使用没有delta的基元?Java是否在后台执行某些已考虑默认delta值的内容?

谢谢.

Pét*_*rök 17

没有使用JUnit断言方法与签名

assertEquals(Double expected, Double result);
Run Code Online (Sandbox Code Playgroud)

但是,对象有一个通用的:

assertEquals(Object expected, Object result);
Run Code Online (Sandbox Code Playgroud)

这会调用对象的equals方法,正如您所料,不建议将其用于比较Double对象.

对于双精度数,正如您所观察到的,绝对有必要使用delta进行比较,以避免浮点舍入问题(在其他一些答案中已有解释).如果使用assertEqualsdouble参数的3参数版本

assertEquals(double expected, double actual, double delta);
Run Code Online (Sandbox Code Playgroud)

你的Doubles将被静默地取消装箱double,一切都会正常工作(你的测试不会意外地失败:-).

  • 我的经验是,在某些情况下,尤其是当您的数据变化幅度较大时,这些方法不能很好地应用于大量数据。两个数字可能有很小的百分比误差,但是需要一个看似较大的增量来匹配。但是,对于数据中的较小值,相同的增量将无效。在某些情况下,甚至可以预期非常大的数字几乎可以匹配所有有效数字。在其他情况下,例如在比较两种优化的FFT算法时,这种可能性要小得多。一种更可靠的方法是限制相对误差。 (2认同)

Lou*_*man 5

双重数学很少,如果给出完全相同的结果.例如,0.1 * 0.1 != 0.01.在比较双精度结果时,通常至少需要一些增量.

另一方面,如果你比较盒装Double,它假设你想要完全相等.Java没有考虑默认的delta值,但Double.equals行为略有不同==:特别是它对NaN的处理.

这在测试中是有意义的,因为Double.NaN != Double.NaN,但是在测试中,如果你期望NaN并且NaN被返回,这是一个正确的答案.


Mor*_*zov 5

最好这样写:

assertEquals(23.0, 250.0, 0.0)  
Run Code Online (Sandbox Code Playgroud)

0.0 - 它是增量。阅读为什么不推荐使用您的方法。