如何正确Stub泛型类SerSup<Cap>作为SomeClass构造函数首个参数?
如何正确Stub泛型类型SerSup作为SomeClass构造函数的参数?
我来帮你解决这个Spock Stub泛型参数的问题,先直接给你正确写法,再分析你之前尝试的问题所在。
正确的Stub方式
方式1:基础Stub + 泛型类型转换
Groovy语法不支持直接在Stub()里写泛型尖括号(比如Stub(SerSup<Cap>)),但我们可以先Stub原始的SerSup类型,再通过类型转换指定泛型:
// 先创建SerSup的Stub,再转为泛型版本 def capSupStub = Stub(SerSup) as SerSup<Cap> def someClass = new SomeClass(capSupStub, "foo", "bar")
或者更简洁的一行写法:
def someClass = new SomeClass(Stub(SerSup) as SerSup<Cap>, "foo", "bar")
方式2:为Stub定义方法行为(如果需要调用SerSup的方法)
如果你的SerSup<Cap>接口有需要调用的方法(比如Cap get()),一定要在Stub里预先定义该方法的返回行为,否则运行时会抛出方法找不到的异常:
// 先Stub泛型参数Cap的实例(如果需要) def capStub = Stub(Cap) // 再Stub SerSup,并指定get()方法返回capStub def capSupStub = Stub(SerSup) { get() >> capStub } // 转换为泛型类型后传入构造函数 def someClass = new SomeClass(capSupStub as SerSup<Cap>, "foo", "bar")
分析你之前的错误
第一次尝试的问题:
Stub(SerSup<Cap>)
Groovy编译器无法解析这种写法——Spock的Stub()方法接收的是Class类型参数,而泛型类型在运行时会被擦除,不存在SerSup<Cap>.class这个东西,只能传入SerSup.class,再通过类型转换来处理泛型的编译提示。第二次尝试的问题:
Stub(Cup) as SerSup<Cup>
这里你Stub的是Cap(应该是笔误写成Cup?)类型,但实际上需要Stub的是SerSup这个泛型接口/类。你把Cap的Stub强制转成SerSup,导致代理对象本质上是Cap的实例,没有SerSup的方法(比如get()),所以调用时会抛出MissingMethodException。
内容的提问来源于stack exchange,提问作者Loom
相关产品推荐
相关产品推荐

