I upgrade to Grails 2.3 recently and try to migrate all old tests to spock integration test. But it fails at cleanup because my test is non-transactional. The Grails doc says test can be non-transactional, but we need to handle it manually, but it seems not quite right here. as I am getting this error in every integration test extending IntegrationSpec
java.lang.IllegalStateException: Cannot deactivate transaction synchronization - not active
at grails.test.spock.IntegrationSpec.cleanup(IntegrationSpec.groovy:72)
A simple test like this would throw that error:
import grails.test.spock.IntegrationSpec
public class DummySpec extends IntegrationSpec {
static transactional = false
def setup() {
}
def cleanup() {
}
def testDummy() {
expect:
1 == 1
}
}
I ran into this too! Pretty sure its a grails bug... I submitted a jira and a patch.
The error is thrown because the code in grails.test.spock.IntegrationSpec does not check for interceptor.isTransactional()
before calling interceptor.destroy()
def cleanup() {
perMethodRequestEnvironmentInterceptor?.destroy()
perMethodTransactionInterceptor?.destroy() //breaks :(
}
...
private GrailsTestTransactionInterceptor initTransaction() {
def interceptor = new GrailsTestTransactionInterceptor(applicationContext)
if (interceptor.isTransactional(this)) interceptor.init() //also need for destroy()
interceptor
}
My fix was to add this code:
def cleanup() {
perMethodRequestEnvironmentInterceptor?.destroy()
destroyTransaction(perMethodTransactionInterceptor)
}
...
private void destroyTransaction(GrailsTestTransactionInterceptor interceptor){
if (interceptor?.isTransactional(this)) interceptor.destroy()
}
To work around for now, you can just create your own com.myname.IntegrationSpec with the patched code and extend that instead of grails.test.spock.IntegrationSpec. Not ideal... but it works :)
Grails 2.3 ships by default with Spock. Just remove your own defined spock dependency make sure to import grails.test.spock.IntegrationSpec and it should work.