断言等于 int long float

新手上路,请多包涵

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

Assert.assertEquals(1,1L)

因 java.lang.AssertionError 失败:预期:java.lang.Integer<1> 但为:java.lang.Long<1>

我希望某处有一个很好的方法,它只比较值并与 int、long、float、byte、double、BigDecimal、BigInteger 一起工作,你可以命名它……

原文由 Pavel Niedoba 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 452
2 个回答

One workaround with some overhead would be to wrap the values in BigDecimal objects, as BigDecimal constructor overloads take long , int and double primitives .

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

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

应该为你工作。

编辑

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

原文由 Mena 发布,翻译遵循 CC BY-SA 3.0 许可协议

根据我对 JLS 的阅读,

 Assert.assertEquals(1,1L)

应该下定决心

Assert.assertEquals(long, long)

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

(备案, assertEquals(long, long)assertEquals(float, float)assertEquals(double, double) _适用于严格调用_,第一个 J.2.15 是最具体的;严格的调用上下文允许原语扩展,但不允许装箱或拆箱。)

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

如果这就是您的真实代码中发生的情况,那么我怀疑使用 is(T) Matcher 的建议是否可行。 is(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 也可以。

原文由 Stephen C 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题