断言等于整长浮点数

2022-09-01 12:08:43

有没有一种优雅的方法来断言数字是相等的,同时忽略它们的类?我想在JUnit测试框架中使用它,但例如

Assert.assertEquals(1,1L)

失败 java.lang.AssertionError: expected: java.lang.Integer<1> 但 was: java.lang.Long<1>

我希望在某个地方有一个很好的方法,它只比较值,并与int,long,float,byte,double,BigDecimal,BigInteger一起使用,你可以说出它......


答案 1

一种开销的解决方法是将值包装在 BigDecimal 对象中,因为构造函数重载采用 和 基元。BigDecimallongintdouble

由于持有,new BigDecimal(1l).equals(new BigDecimal(1.0))true

Assert.assertEquals(new BigDecimal(1.0), new BigDecimal(1l));  

应该为你工作。

编辑

正如绿巨人在下面所说,对象的比例用于比较,但不用于比较。虽然比例设置为构造函数 take 的默认值,但它是通过构造函数 take 中的一些计算来推断的。因此,比较值的最安全方法(即在值的边缘情况下)可能是通过调用和检查结果。BigDecimalequalscompareTo0longdoubledoublecompareTo0


答案 2

根据我对JLS的阅读,重载分辨率

Assert.assertEquals(1,1L)

应解析为

Assert.assertEquals(long, long)

简而言之,问题中的代码片段不是实际问题的有效示例。

(对于记录,,和可以通过严格调用来应用,第一个是最具体的;请参阅 JLS 15.12.2.2。严格的调用上下文允许原始加宽,但不允许装箱或取消装箱。assertEquals(long, long)assertEquals(float, float)assertEquals(double, double)

如果(如证据所示)您的调用解析为 ,则意味着其中一个操作数必须已经是盒装类型。该重载的问题在于它使用该方法来比较对象,并且该方法的协定指定结果是对象的相应类型是否不同。Assert.assertEquals(Object, Object)equals(Object)false

如果这就是你真正的代码中发生的事情,那么我怀疑使用的建议是否有效。匹配器等同于后者依赖于...is(T)Matcheris(T)is(equalTo(T))equals(Object)

有没有现有的“好方法”?

AFAIK,没有。

我认为真正的解决方案是更加关注类型;例如:

 int i = 1;
 Long l = 1L;
 Assert.assertEquals(i, l);         // Fails
 Assert.assertEquals((long) i, l);  // OK - assertEquals(Object, Object)
 Assert.assertEquals((Long) i, l);  // OK - assertEquals(Object, Object)
 Assert.assertEquals(i, (int) l);   // OK - assertEquals(long, long) 
                                    //      it would bind to an (int, int) 
                                    //      overload ... it it existed.   
 Assert.assertEquals(i, (long) l);  // OK - assertEquals(long, long)


 

编写自定义也可以。Matcher


推荐