I have this code in Spock:
then:
1 * dao.getByValue(Something.ONE, _ as String) >> {Something smth, String value ->
return createSomething(smth).withValue(value).build()
}
It doesn't look exactly like that, but you get the point. I want to return an object based on arguments passed to the method, in the real version this object is loaded from database.
The point is that I have this call in a lot of places and it looks exactly the same everywhere. Could I somehow extract this closure and use it everywhere, like this:
then:
1 * dao.getByValue(Something.ONE, _ as String) >> Closures.makeSomething
I tried using Intellij extract feature, but it kinda went crazy there with types, after I edited the types manually I had weird errors:
public static final Closure<Optional<Something>> makeSomething = { Something smth, String value ->
return createSomething(smth).withValue(value).build()
}
...
1 * dao.getByValue(Something.ONE, _ as String) >> makeSomething
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'mypackage.MySpec$__clinit__closure1@1757cd72' with class 'mypackage.MySpec$__clinit__closure1' to class 'java.util.Optional'
Even that one didn't work, and I thought it would:
public static final Closure<Optional<Something>> makeSomething = { Something smth, String value ->
return createSomething(smth).withValue(value).build()
}
...
1 * dao.getByValue(Something.ONE, _ as String) >> {args -> makeSomething.call(args[0], args[1]) }
groovy.lang.MissingMethodException: No signature of method: mypackage.MySpec$__clinit__closure2.call() is applicable for argument types: (java.util.Arrays$ArrayList) values: [[mypackage.Something$$Lambda$6/1105423942@6f45df59, ...]]
I'm not good at Groovy or Spock in general, I'm just trying this out for now.
Edit:
Working code after @tim_yates suggestion (whole interaction is in the helper method):
then:
interaction {
somethingCall(2, Something.TWO)
somethingCall(3, Something.ONE)
}
}
private void somethingCall(int times, Something something) {
times * dao.getByValue(something, _ as String) >> { Something smth, String value ->
return createSomething(smth).withValue(value).build()
}
}
Not working code that I'd like (only the return value is in the helper method):
then:
2 * dao.getByValue(Something.TWO, _ as String) >> makeSomething
3 * dao.getByValue(Something.ONE, _ as String) >> makeSomething
}
public static final Closure<Optional<Something>> makeSomething = { Something smth, String value ->
return createSomething(smth).withValue(value).build()
}
If I simply inline each >> makeSomething
and write there it's body instead, then it works.