问题描述
我无法为通用类创建编译Spock存根.构造函数的签名如下:
I cannot make compile Spock stub for generic class. The signature of constructor is following:
SomeClass(SerSup<Cap> capSup, String foo, String bar);
我需要将第一个参数存根.以下是我失败的尝试.
I need to stub the first argument. The following are my failed attempts.
第一次尝试:
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
构造函数的第一个参数的正确方法是什么?
What is the right way to stub first argument of SomeClass
constructor?
推荐答案
您的第二次尝试失败,因为您无法将 Stub(Cap)
强制转换为 SerSup< Cap>
.您必须改为 Stub(SerSup)
,或者您可以应用我在下面描述的建议.
Your second attempt failed because you cannot cast Stub(Cap)
to SerSup<Cap>
. You would have to Stub(SerSup)
instead, or you could apply the suggestions I have described below.
我建议在初始化 SomeClass
之前为您的存根创建一个变量.您可以使用 Stub(type:...)
构造函数对通用类进行存根,例如
I would recommend creating a variable for your stub before initializing SomeClass
. You can stub generic class using Stub(type: ...)
constructor, e.g.
SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>
此初始化不会在您的IDE中产生任何警告.如果您可以接受一些警告,可以将其简化为:
This initialization does not produce any warning in your IDE. If you are ok with some warnings you can simplify it to:
def serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type)
或者,您可以尝试类似的操作:
Alternatively, you could try something like:
SerSup<String> serSup = Stub(SerSup) {
get() >> ""
}
此替代解决方案需要存根方法返回有效类型,否则将返回 new Object()
的等效项.在第一种情况下,默认"为默认".返回值,因为我们满足了所有类型检查的要求(例如,在 String
的情况下,返回的是空字符串).
This alternative solution requires stubbing methods to return valid type, otherwise it returns the equivalent of new Object()
. In the first case, "default" values are returned, because we satisfied all type checks (e.g. in case of a String
, an empty string returned).
下面是显示两种方法的示例:
Here is an example that shows both approaches:
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
}
}
}
这篇关于Spock存根的泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!