【发布时间】:2014-07-14 16:05:20
【问题描述】:
在我的 Eclipse 项目中,我有一个 java 类,它使用重载方法验证不同类型的对象是否为空:
public class EmptyProof {
public static boolean isEmpty(String field) {
System.out.println("String " + field);
return field == null || field.trim().equals("");
}
public static boolean isEmpty(BigDecimal d) {
System.out.println("BI " + d.toString());
return d == null || d.compareTo(new BigDecimal("0")) == 0;
}
public static boolean isEmpty(Object input) {
System.out.println("obj " + input.toString());
return input == null || String.valueOf(input).length() == 0;
}
}
现在我想在 Spock 中编写一个单元测试:
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import spock.lang.Specification;
class EmptyProofSpec extends Specification {
def 'must evaluate emptiness of a String correctly'() {
expect: "isEmpty for String returns the right answer"
System.out.println("test string " + bi.toString());
EmptyProof.isEmpty(str as String) == result
where: "using this table"
str || result
"" || true
null || true
"a" || false
}
def 'must evaluate emptiness of a BigInteger correctly'() {
expect:
System.out.println("test BigInt " + bi.toString());
EmptyProof.isEmpty(bi as BigInteger) == result
where: "using this table"
bi || result
BigInteger.ONE || false
new BigInteger(Integer.MIN_VALUE) as BigInteger || false
// null as BigInteger || true
// BigInteger.ZERO as BigInteger || true
}
}
这会在控制台中为我带来以下输出:
test string
String
test string null
test string a
String a
test BigInt 1
obj 1
test BigInt -2147483648
obj -2147483648
如您所见,我使用 String 对象调用 isEmpty(String) 进行的测试。但是我对 BigInteger 的调用不是调用 isEmpty(BigInteger),而是调用 isEmpty(Object)。我想用 BigInteger.ZERO 添加我的测试,但这会失败,因为 Object-method 不关心 0。
我已经尝试了一些东西,比如强制转换和@CompileStatic 注释。然而没有成功。
我可以指示 Spock 使用 BigInteger 方法而不更改我的 Java 类吗?
【问题讨论】:
-
EmptyProof必须是 Java 类吗?如果它是一个 Groovy 类,您将不会看到这个问题,因为与 Java 相比,Groovy 中使用了运行时调度或多方法。与在编译时选择方法的 Java 相比,将在运行时根据参数的类型选择适当的方法调用。 -
Groovy 在调用 Java 类中的方法时也会执行多次分派。
-
这来自一个超过 100k loc 的项目。在引入单元测试的保存库之前,我不想改变任何事情。
标签: java groovy overloading spock