It's very simple to create a CreateUnitSpec or CreateIntegrationSpec script with a template specification. Hooking in to the other types of artifact creation turned out to be fiddlier. Each create-* command calls a Closure called createUnitTest. Reassigning that Closure should be the solution. The trick is in figuring out where that can be done.
Any time one of its Gant targets is invoked the Grails build system fires an event. You can respond to those events by declaring a closure called
event<target name>Start
in scripts/_Events.groovy
. The only Gant target directly invoked when an artifact is created is called 'default'. It is possible to intercept that although that means the event handler will be invoked any time any Gant target called 'default' runs. For this purpose that's no problem since we're just overriding a closure in the build binding.The other factor is that the superclass for the unit test is specified by the individual create-* scripts (or defaulted to GrailsUnitTestCase). Rather than having to override those scripts as well, I've just mapped the non-standard unit test superclasses to the Spock equivalents.
Here's the code for your
_Events.groovy
script:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
eventDefaultStart = { | |
createUnitTest = { Map args = [:] -> | |
def superClass | |
// map unit test superclass to Spock equivalent | |
switch(args["superClass"]) { | |
case "ControllerUnitTestCase": | |
superClass = "ControllerSpec" | |
break | |
case "TagLibUnitTestCase": | |
superClass = "TagLibSpec" | |
break | |
default: | |
superClass = "UnitSpec" | |
} | |
createArtifact name: args["name"], suffix: "${args['suffix']}Spec", type: "Spec", path: "test/unit", superClass: superClass | |
} | |
} |
The template specification should be placed in
src/templates/artifacts/Spec.groovy
and is simply:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@artifact.package@import spock.lang.* | |
import grails.plugin.spock.* | |
class @artifact.name@ extends @artifact.superclass@ { | |
def "feature method"() { | |
} | |
} |
It goes without saying that this is a slightly hairy and it would be great if Grails provided a proper hook for overriding the test generation. I can live with some fun-size evil in _Events.groovy for the sake of the convenience of getting template specs for all my artifacts, though.