我们有一个名为“Decimal”的自定义类型,它扩展了java.lang.Number
我们正在使用Groovy / Spock进行一些单元/验收测试。
我们在断言中注意到了一些神秘的行为。
在以下代码中,myDecimal的真值为9.91
assert myDecimal == new Decimal(“9.91”) // succeed.
assert myDecimal == new Decimal(“9.02”) // succeed. What??
assert myDecimal == new Decimal(“8.99”) // fail.
我们的一位开发人员在org.codehaus.groovy.runtime.typehandling.NumberMath.java中找到了一些代码[groovy-all-2.2.1]
public static NumberMath getMath(Number left, Number right) {
if (isFloatingPoint(left) || isFloatingPoint(right)) {
return FloatingPointMath.INSTANCE;
}
if (isBigDecimal(left) || isBigDecimal(right)) {
return BigDecimalMath.INSTANCE;
}
if (isBigInteger(left) || isBigInteger(right)) {
return BigIntegerMath.INSTANCE;
}
if (isLong(left) || isLong(right)){
return LongMath.INSTANCE;
}
return IntegerMath.INSTANCE;
}
看到这个方法很明显,我们的自定义Decimal类将被分配一个IntegerMath。在断言非整数时会导致“破坏”的断言。
有没有人知道解决这个问题的方法?例如有没有办法提供NumberMath对象的自定义工厂?
任何帮助都会非常感激。
答案 0 :(得分:0)
我看到两种解决方法: 1.如果其中一个可用的Math实例(比如BigDecimalMath)可以正确地比较您的数字,那么相应地更改Decimal的基类 2.否则,尝试更改NumberMath的元类中的getMath方法。它很脏,我甚至不确定是否可以使用Metaclass改变Groovy本身。那就是说,我想在一个空闲时刻检查出来......