Grails中,创建脚手架(诸如,Domain类、Controller、Taglib)时,会自动创建相关的JUnit测试用例。如果你在使用Spock,一定也希望能够为脚手架生成Spock spec。用什么方法呢?Robert Fletcher在博文中,分享了他的方法--重定义事件处理器。
由于Grails在构建系统时,会调用Gant激活事件处理器,那么只需要重新定义事件处理器,让其在创建脚手架时生成Spock spec。具体步骤如下:
- Grails中,事件处理器在scripts/_Events.groovy中以闭包的形式进行定义。这里Robert Fletcher创建了一个名为eventDefaultStart的闭包,其中包含了Gant执行default target之前,要触发执行的代码。代码如下:
- 接下来就要为上述代码中用到的type: "Spec",创建一个Spec.groovy。如果还未安装template,请使用:grails install-templates进行安装。
- 在src/templates/artifacts/目录下会看到各种脚手架的模板文件,Spec.groovy存放的位置也在这里,其代码如下:
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
}
}
上述代码中,事件处理器的命名方式是event<target>start,意思是在执行target之前执行这个事件处理器中的代码。代码中的createUnitTest、createArtifact均为Gant的target。由于每个Create***脚本都会调用createUnitTest,这里重写了createUnitTest。当执行Create***命令创建脚手架(Controller、TagLib、Unit)时,就会执行调用createUnitTest,为脚手架在test/unit目录下,根据Spec模板创建***Spec文件。
@artifact.package@import spock.lang.*
import grails.plugin.spock.*
class @artifact.name@ extends @artifact.superclass@ {
def "feature method"() {
}
}
上述步骤完成后,执行Create*命令时,就会生成相关的Spock pec文件了。的确很简单。你也同样可以采用此法,定制自己的测试。:)
关于Grails的事件处理,可参见Grails 1.2参考文档速读(5):第4章

未来的Grails-Spock插件可能会加上这个功能
从原文的评论看,这个脚本在未来会合并到grails-spock插件里,以后就不用自己来加了。