Java 带有Spock存根的泛型

Java 带有Spock存根的泛型,java,unit-testing,generics,groovy,spock,Java,Unit Testing,Generics,Groovy,Spock,我不能为泛型类编译Spock存根。建造商签字如下: SomeClass(SerSup<Cap> capSup, String foo, String bar); SomeClass(SerSup capSup、String foo、String bar); 我需要打断第一个论点。以下是我失败的尝试 第一次尝试: def someClass = new SomeClass(Stub(SerSup<Cap>), "foo", "bar") Error: Groovyc:

我不能为泛型类编译Spock存根。建造商签字如下:

SomeClass(SerSup<Cap> capSup, String foo, String bar);
SomeClass(SerSup capSup、String foo、String bar);
我需要打断第一个论点。以下是我失败的尝试

第一次尝试:

def someClass = new SomeClass(Stub(SerSup<Cap>), "foo", "bar")

Error: Groovyc: unexpected token: >
Status bar: ',' or ')' expected
defsomeclass=newsomeclass(存根(SerSup),“foo”,“bar”)
错误:Groovyc:意外标记:>
状态栏应为“,”或“)”
另一种尝试:

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)
def someClass=新的someClass(存根(杯)作为SerSup,“foo”,“bar”)
groovy.lang.MissingMethodException:没有方法com.sun.proxy的签名。$Proxy10.get()适用于参数类型:()值:[]
可能的解决方案:grep()、getAt(java.lang.String)、grep(java.lang.Object)、wait()、any()、wait(long)
at loom.SomeClass.SomeMethod(SomeClassTest.groovy:14)

什么是存根
SomeClass
构造函数的第一个参数的正确方法?

您的第二次尝试失败,因为您无法将
stub(Cap)
强制转换为
SerSup
。您必须改为
Stub(SerSup)
,或者您可以应用我在下面描述的建议

我建议在初始化
SomeClass
之前为存根创建一个变量。您可以使用
存根(类型:…)
构造函数存根泛型类,例如

SerSup<String> serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type) as SerSup<String>

@Szymon给出了很好的解释,但是我建议不要使用泛型,在这里使用普通的
存根(SerSub)
。@LeonardBrüngs-谢谢。实际上,我不清楚如何“放弃泛型”。我的代码示例中的泛型与实际类的测试一起进行。是否有一些技巧可以帮助摆脱泛型?或者你指的是什么?Java通过类型擦除实现了泛型,这意味着当它们被写入字节码时会被删除。因此,对于java,
List
在运行时将是
List
。仅使用
列表
是完全合法的(只是警告)。你犯的唯一错误是把你的类型弄混了。使用该示例,您尝试将
String
而不是
List
存根,并将其转换为
List
,但实际效果并不理想。因此,只需使用
Stub(SerSub)
而不是
Stub(Cap)
,它就可以工作了。
def serSup = Stub(type: new TypeToken<SerSup<String>>(){}.type)
SerSup<String> serSup = Stub(SerSup) {
    get() >> ""
}
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
        }
    }
}