spockframework / spockframework/spock
Accessing Spring from custom extension: Change global extension execution order
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 3.6k
- Forks
- 483
- PR merge metrics
- No merged PRs in 30d
Description
Issue description
Currently global extensions are executed in the order they are discovered in the class path. That poses a problem when writing custom extensions which try to access fields in the Specification which will be initialized by Spring via @Autowired.
When I have MyGlobalExtension in MyProject, which depends on spock-spring and last on spock-core, the Spring extension will always add its IMethodInterceptors after MyGlobalExtension.
As far as I understand, there are a few possible workarounds (solutions) to the problem:
- Allow defining the order other extensions by listing them
META-INF/services/org.spockframework.runtime.extension.IGlobalExtension, so theglobalExtensionClassesinGlobalExtensionRegistrywould probably become aLinkedHashSet<Class<?>>. This would make the order of extensions configurable explicitly. (BUG: Currently the SpringExtension will be loaded twice if you do add it to your own extension configuration file) - Reverse the order of Extensions before execution in
ExtensionRunner:
private void runGlobalExtensions() {
final List<IGlobalExtension> globalExtensions = new ArrayList<IGlobalExtension>(extensionRegistry.getGlobalExtensions());
Collections.reverse(globalExtensions);
for (IGlobalExtension extension : globalExtensions) {
extension.visitSpec(spec);
}
}
This ensures that all extensions in dependencies are loaded first, but would not fix the problem between extensions in different dependencies on the classpath
- Always load the Spring extension first programatically
I will happily contribute a fix along with tests and a Gist if required :)
Java/JDK
java -version
1.7+
Groovy version
Note that versions older than 2.0 are no longer supported.
groovy -version
2.4
Build tool version
Gradle
gradle -version
Gradle wrapper from spock-example project
Operating System
Windows 10
IDE
IntelliJ
Build-tool dependencies used
Gradle/Grails
compile 'org.spockframework:spock-core:1.1-groovy-2.4'
compile 'org.spockframework:spock-spring:1.1-groovy-2.4'
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read GlobalExtensionRegistry and ExtensionRunner first, then inspect the META-INF/services/org.spockframework.runtime.extension.IGlobalExtension configuration mentioned in the issue. Identify the existing tests covering global extension loading and ordering. Done means the chosen ordering behavior is implemented, duplicate SpringExtension loading is addressed, and custom extensions can access Spring-initialized fields.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- groovy, java
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100