我们有一个名为“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对象的自定义工厂?
任何帮助都会非常感激 .
1 回答
我看到两种解决方法:1 . 如果其中一个可用的Math实例(比如BigDecimalMath)可以正确地比较你的数字,那么相应地更改你的Decimal的基类2.否则,尝试更改NumberMath的元类中的getMath方法 . 它很脏,我甚至不确定是否可以使用Metaclass改变Groovy本身 . 那就是说,我想在一个空闲时刻检查出来......