Skip to content

Commit 0432f2d

Browse files
committed
Fixes problems with Spock and @Rollback - Fixes #9493
1 parent 69f283a commit 0432f2d

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

grails-core/src/main/groovy/org/grails/transaction/transform/TransactionalTransform.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ class TransactionalTransform implements ASTTransformation{
117117
if (!md.isSynthetic() && Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers) && !Modifier.isStatic(modifiers)) {
118118
if(hasExcludedAnnotation(md)) continue
119119

120-
if( methodName.contains('$') && !methodName.startsWith('$spock') ) continue
120+
def startsWithSpock = methodName.startsWith('$spock')
121+
if( methodName.contains('$') && !startsWithSpock) continue
122+
123+
if(startsWithSpock && methodName.endsWith('proc') ) continue
121124

122125
if(md.getAnnotations().any { AnnotationNode an -> an.classNode.name == "org.spockframework.runtime.model.DataProviderMetadata"}) {
123126
continue

grails-test-suite-uber/src/test/groovy/grails/transaction/TransactionalTransformSpec.groovy

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.codehaus.groovy.control.MultipleCompilationErrorsException
2121
import org.springframework.beans.factory.annotation.Autowired
2222
import org.springframework.beans.factory.annotation.Qualifier
2323
import org.springframework.transaction.PlatformTransactionManager
24+
import org.springframework.util.ReflectionUtils
2425

2526
import javax.annotation.PostConstruct
2627
import javax.sql.DataSource
@@ -112,12 +113,55 @@ class DemoSpec extends Specification {
112113

113114
then:"It implements TransactionManagerAware"
114115
TransactionManagerAware.isAssignableFrom(mySpec)
115-
mySpec.getDeclaredMethod('$spock_feature_0_0')
116+
mySpec.getDeclaredMethod('$spock_feature_0_0', Object, Object)
117+
mySpec.getDeclaredMethod('$spock_feature_0_0proc', Object, Object)
116118
mySpec.getDeclaredMethod('$spock_feature_0_0prov0')
117-
!mySpec.getDeclaredMethod('$tt__$spock_feature_0_0prov0')
118-
mySpec.getDeclaredMethod('$tt__$spock_feature_0_0', TransactionStatus)
119+
120+
!ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0prov0', TransactionStatus)
121+
ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0', Object, Object, TransactionStatus)
122+
!ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0proc', Object, Object, TransactionStatus)
119123
}
120124

125+
void "Test @Rollback when applied to Spock specifications on a method and where blocks"() {
126+
when:"A new instance of a class with a @Transactional method is created that subclasses another transactional class"
127+
Class mySpec = new GroovyShell().evaluate('''
128+
import grails.test.mixin.integration.Integration
129+
import grails.transaction.Rollback
130+
import spock.lang.Specification
131+
132+
@Integration
133+
134+
class DemoSpec extends Specification {
135+
136+
@Rollback
137+
def "test toUpperCase"() {
138+
given:
139+
def result = value.toUpperCase()
140+
141+
expect:
142+
result == expectedResult
143+
144+
where:
145+
value | expectedResult
146+
'King Crimson' | 'KING CRIMSON\'
147+
'Riverside' | 'RIVERSIDE\'
148+
}
149+
}
150+
DemoSpec
151+
''')
152+
153+
then:"It implements TransactionManagerAware"
154+
TransactionManagerAware.isAssignableFrom(mySpec)
155+
mySpec.getDeclaredMethod('$spock_feature_0_0', Object, Object)
156+
mySpec.getDeclaredMethod('$spock_feature_0_0proc', Object, Object)
157+
mySpec.getDeclaredMethod('$spock_feature_0_0prov0')
158+
159+
!ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0prov0', TransactionStatus)
160+
ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0', Object, Object, TransactionStatus)
161+
!ReflectionUtils.findMethod(mySpec, '$tt__$spock_feature_0_0proc', Object, Object, TransactionStatus)
162+
}
163+
164+
121165
@Issue('#701')
122166
void "Test @Transactional with a datasource specified isn't TransactionManager aware, but has appropriate autowired and qualifier"() {
123167
when:"A new instance of a class with a @Transactional method is created that subclasses another transactional class"

0 commit comments

Comments
 (0)