带有 Spock Stub 的泛型
Generics with Spock Stub
我无法为通用 class 编译 Spock 存根。构造函数的签名如下:
SomeClass(SerSup<Cap> capSup, String foo, String bar);
我需要存根第一个参数。以下是我失败的尝试。
第一次尝试:
def someClass = new SomeClass(Stub(SerSup<Cap>), "foo", "bar")
Error: Groovyc: unexpected token: >
Status bar: ',' or ')' expected
再试一次:
def someClass = new someClass(Stub(Cup) as SerSup<Cup>, "foo" ,"bar")
groovy.lang.MissingMethodException: No signature of method: com.sun.proxy.$Proxy10.get() is applicable for argument types: () values: []
Possible solutions: grep(), getAt(java.lang.String), grep(java.lang.Object), wait(), any(), wait(long)
at loom.SomeClass.SomeMethod(SomeClassTest.groovy:14)
存根 SomeClass
构造函数的第一个参数的正确方法是什么?
您的第二次尝试失败,因为您无法将 Stub(Cap)
转换为 SerSup<Cap>
。您将不得不 Stub(SerSup)
,或者您可以应用我在下面描述的建议。
我建议在初始化 SomeClass
之前为存根创建一个变量。您可以使用 Stub(type: ...)
构造函数存根通用 class,例如
SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>
此初始化不会在您的 IDE 中产生任何警告。如果您对一些警告没有意见,您可以将其简化为:
def serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type)
或者,您可以尝试类似的操作:
SerSup<String> serSup = Stub(SerSup) {
get() >> ""
}
此替代解决方案需要将方法存根到 return 有效类型,否则它 return 等同于 new Object()
。在第一种情况下,“默认”值是 returned,因为我们满足所有类型检查(例如,在 String
的情况下,空字符串 returned)。
下面是一个展示这两种方法的例子:
import com.google.common.reflect.TypeToken
import spock.lang.Specification
class StubSpec extends Specification {
def "test stubbing with default value for String"() {
when:
SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>
then:
serSup.get() == ""
}
def "test stubbing without explicit type"() {
when:
SerSup<String> serSup = Stub(SerSup) {
get() >> "lorem ipsum"
}
then:
serSup.get() == "lorem ipsum"
}
static class SerSup<T> {
private final T obj
SerSup(T t) {
this.obj = t
}
T get() {
return obj
}
}
}
我无法为通用 class 编译 Spock 存根。构造函数的签名如下:
SomeClass(SerSup<Cap> capSup, String foo, String bar);
我需要存根第一个参数。以下是我失败的尝试。
第一次尝试:
def someClass = new SomeClass(Stub(SerSup<Cap>), "foo", "bar")
Error: Groovyc: unexpected token: >
Status bar: ',' or ')' expected
再试一次:
def someClass = new someClass(Stub(Cup) as SerSup<Cup>, "foo" ,"bar")
groovy.lang.MissingMethodException: No signature of method: com.sun.proxy.$Proxy10.get() is applicable for argument types: () values: []
Possible solutions: grep(), getAt(java.lang.String), grep(java.lang.Object), wait(), any(), wait(long)
at loom.SomeClass.SomeMethod(SomeClassTest.groovy:14)
存根 SomeClass
构造函数的第一个参数的正确方法是什么?
您的第二次尝试失败,因为您无法将 Stub(Cap)
转换为 SerSup<Cap>
。您将不得不 Stub(SerSup)
,或者您可以应用我在下面描述的建议。
我建议在初始化 SomeClass
之前为存根创建一个变量。您可以使用 Stub(type: ...)
构造函数存根通用 class,例如
SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>
此初始化不会在您的 IDE 中产生任何警告。如果您对一些警告没有意见,您可以将其简化为:
def serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type)
或者,您可以尝试类似的操作:
SerSup<String> serSup = Stub(SerSup) {
get() >> ""
}
此替代解决方案需要将方法存根到 return 有效类型,否则它 return 等同于 new Object()
。在第一种情况下,“默认”值是 returned,因为我们满足所有类型检查(例如,在 String
的情况下,空字符串 returned)。
下面是一个展示这两种方法的例子:
import com.google.common.reflect.TypeToken
import spock.lang.Specification
class StubSpec extends Specification {
def "test stubbing with default value for String"() {
when:
SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>
then:
serSup.get() == ""
}
def "test stubbing without explicit type"() {
when:
SerSup<String> serSup = Stub(SerSup) {
get() >> "lorem ipsum"
}
then:
serSup.get() == "lorem ipsum"
}
static class SerSup<T> {
private final T obj
SerSup(T t) {
this.obj = t
}
T get() {
return obj
}
}
}