如何使用 spock "where" table 测试重载方法
How to test overloaded method using spock "where" table
我想测试将 null
传递给这些重载方法:
public static Object someMethod(String n) { /* some impl */ }
public static Object someMethod(Integer n) { /* some impl */ }
我试过了:
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
null as String | someValue
null as Integer | someValue
}
但我收到错误消息:
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method com.foo.MyClass#someMethod.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class java.lang.String]
[class java.lang.Integer]
如何使用一种 spock 方法在 where
块(具有其他值)中输入空值来测试这些?
我试图用 Spock 1.3 和 Groovy 2.5.8 重现您的问题,但没成功。相反,我遇到了另一个 Spock 问题,请参阅 here。您必须使用其他版本的 Spock and/or Groovy.
无论如何,我刚刚链接到的 Spock bug 的一个解决方法是不从 then:
或 expect:
块调用带有空参数的方法,而是从 when:
和稍后在 then:
块中进行比较。另请参阅我的代码示例。
除此之外,您需要将特征方法拆分为两种方法,一种用于您要测试的每种类型的 null
对象。
Java class 测试中:
package de.scrum_master.Whosebug.q58279620;
public class ClassUnderTest {
public static Object someMethod(String n) {
return n == null ? "nothing" : "something";
}
public static Object someMethod(Integer n) {
return n == null ? -999 : 11;
}
}
Spock 测试解决方法:
package de.scrum_master.Whosebug.q58279620
import spock.lang.Specification
import spock.lang.Unroll
class PassingNullToOverloadedMethodTest extends Specification {
@Unroll
def "someMethod('#input') returns #expected"() {
when:
def result = ClassUnderTest.someMethod(input as String)
then:
result == expected
where:
input | expected
"foo" | "something"
"" | "something"
null | "nothing"
}
@Unroll
def "someMethod(#input) returns #expected"() {
when:
def result = ClassUnderTest.someMethod(input as Integer)
then:
result == expected
where:
input | expected
0 | 11
123 | 11
null | -999
}
}
在这种情况下,类型转换不会被继承,也不能被 Spock 继承。
但是您可以手动使用 PojoWrapper
,这就是 Groovy 在内部表示 type-casted null
:
的方式
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
new PojoWrapper(null, String) | someValue
new PojoWrapper(null, Integer) | someValue
}
但有一个重要提示,第一组输入必须包含包装器,否则 Groovy 以不解包参数的方式优化 someMethod
调用。
所以这会起作用:
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
new PojoWrapper(null, Integer) | someValue
0 | someValue
}
虽然这行不通,但抛出 ClassCastException
:
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
0 | someValue
new PojoWrapper(null, Integer) | someValue
}
我想测试将 null
传递给这些重载方法:
public static Object someMethod(String n) { /* some impl */ }
public static Object someMethod(Integer n) { /* some impl */ }
我试过了:
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
null as String | someValue
null as Integer | someValue
}
但我收到错误消息:
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method com.foo.MyClass#someMethod.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class java.lang.String]
[class java.lang.Integer]
如何使用一种 spock 方法在 where
块(具有其他值)中输入空值来测试这些?
我试图用 Spock 1.3 和 Groovy 2.5.8 重现您的问题,但没成功。相反,我遇到了另一个 Spock 问题,请参阅 here。您必须使用其他版本的 Spock and/or Groovy.
无论如何,我刚刚链接到的 Spock bug 的一个解决方法是不从 then:
或 expect:
块调用带有空参数的方法,而是从 when:
和稍后在 then:
块中进行比较。另请参阅我的代码示例。
除此之外,您需要将特征方法拆分为两种方法,一种用于您要测试的每种类型的 null
对象。
Java class 测试中:
package de.scrum_master.Whosebug.q58279620;
public class ClassUnderTest {
public static Object someMethod(String n) {
return n == null ? "nothing" : "something";
}
public static Object someMethod(Integer n) {
return n == null ? -999 : 11;
}
}
Spock 测试解决方法:
package de.scrum_master.Whosebug.q58279620
import spock.lang.Specification
import spock.lang.Unroll
class PassingNullToOverloadedMethodTest extends Specification {
@Unroll
def "someMethod('#input') returns #expected"() {
when:
def result = ClassUnderTest.someMethod(input as String)
then:
result == expected
where:
input | expected
"foo" | "something"
"" | "something"
null | "nothing"
}
@Unroll
def "someMethod(#input) returns #expected"() {
when:
def result = ClassUnderTest.someMethod(input as Integer)
then:
result == expected
where:
input | expected
0 | 11
123 | 11
null | -999
}
}
在这种情况下,类型转换不会被继承,也不能被 Spock 继承。
但是您可以手动使用 PojoWrapper
,这就是 Groovy 在内部表示 type-casted null
:
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
new PojoWrapper(null, String) | someValue
new PojoWrapper(null, Integer) | someValue
}
但有一个重要提示,第一组输入必须包含包装器,否则 Groovy 以不解包参数的方式优化 someMethod
调用。
所以这会起作用:
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
new PojoWrapper(null, Integer) | someValue
0 | someValue
}
虽然这行不通,但抛出 ClassCastException
:
import org.codehaus.groovy.runtime.wrappers.PojoWrapper
def "test someMethod"() {
expect:
someMethod(input) == expected
where:
input | expected
0 | someValue
new PojoWrapper(null, Integer) | someValue
}