Generics with Spock Stub

故事扮演 提交于 2020-12-31 04:41:45

问题


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.

First try:

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

Error: Groovyc: unexpected token: >
Status bar: ',' or ')' expected

Another try:

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)

What is the right way to stub first argument of SomeClass constructor?


回答1:


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.

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>

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() >> ""
}

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
        }
    }
}


来源:https://stackoverflow.com/questions/48263921/generics-with-spock-stub

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!