migrate-groovy-to-java
Skill739 starsChanged 6 days agoApache-2.0View on GitHub
Converts Spock/Groovy test files in a Gradle module to equivalent JUnit 5 Java tests. Use when asked to "migrate groovy", "convert groovy to java", "g2j", or when a module has .groovy test files that need to be replaced with .java equivalents.
In this repository17 other files it gives its agents.
- AGENTS.mdAGENTS.md
- build-logic/AGENTS.mdAGENTS.md
- buildSrc/AGENTS.mdAGENTS.md
- build-logic/CLAUDE.mdCLAUDE.md
- buildSrc/CLAUDE.mdCLAUDE.md
- .claude/CLAUDE.mdCLAUDE.md
- apm-integrationsSkill
- clarify-java-commentsSkill
- fix-continuation-leakageSkill
- java-lintSkill
- migrate-junit-source-to-tabletestSkill
- perf-reviewSkill
- reproduce-ci-flakinessSkill
- resolve-muzzle-ciSkill
- review-groovy-migrationSkill
- techdebtSkill
- fix-continuation-leakageSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 8 are distinctive, and 13 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
13
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 13
Make sure the tests are still passing after migration and that the test count has not changed
- Distinctive: line 16
When converting Groovy code to Java code, make sure that:
- Very specific: line 18
When translating Spock tests, prefer @TableTest for data rows that are naturally tabular.
- Very specific: line 21
If @TableTest is not viable for the test at all, use @MethodSource only.
- Very specific: line 22
If @TableTest was successfully used and if the @ParameterizedTest is not used to specify the test name, @ParameterizedTest can then be …
- Very specific: line 24
Ensure parameterized test names are human-readable (i.e.
- Distinctive: line 25
When converting tuples, create a light dedicated structure instead to keep the typing system
- Distinctive: line 26
Instead of checking a state and throwing an exception, use JUnit asserts
- Very specific: line 27
Instead of using assertTrue(a.equals(b)) or assertFalse(a.equals(b)), use assertEquals(expected, actual) and assertNotEquals(unexpected, …
- Distinctive: line 28
Import frequently used types rather than using fully-qualified names inline, to improve readability
- Distinctive: line 29
Do not wrap checked exceptions and throw a Runtime exception.
- Very specific: line 30
Do not mark local variables final
- Distinctive: line 31
Ensure variables are human-readable.
- Very specific: line 32
When translating Spock Mock(...) usage, use libs.bundles.mockito instead of writing manual recording/stub implementations
- Very specific: line 55
Add scenario column as first column (display name, not a method parameter).
- Very specific: line 56
Use | delimiter; align columns so pipes line up vertically.
- Very specific: line 57
Prefer single quotes for strings with special chars (e.g., 'a|b', '[]').
- Very specific: line 62
Prefer combining @TableTest + @MethodSource on one @ParameterizedTest when only some cases are complex.
- Very specific: line 63
Use @MethodSource only when tabular representation is not practical for the test.
- Distinctive: line 65
Do NOT use @TableTest when:
- Very specific: line 70
Before writing any Java output, read .claude/skills/migrate-groovy-to-java/QUALITY_RULES.md in full.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Migrate test Groovy files to Java using JUnit 5
- List all Groovy files of the current Gradle module
- Convert Groovy files to Java using JUnit 5
- Make sure the tests are still passing after migration and that the test count has not changed
- Remove Groovy files
When converting Groovy code to Java code, make sure that:
- The Java code generated is compatible with JDK 8
- When translating Spock tests, prefer
@TableTestfor data rows that are naturally tabular. See detailed guidance in the "TableTest usage" section. @TableTestand@MethodSourcemay be combined on the same@ParameterizedTestwhen most cases are tabular but a few cases require programmatic setup.- In combined mode, keep table-friendly cases in
@TableTest, and put only non-tabular/complex cases in@MethodSource. - If
@TableTestis not viable for the test at all, use@MethodSourceonly. - If
@TableTestwas successfully used and if the@ParameterizedTestis not used to specify the test name,@ParameterizedTestcan then be removed as@TableTestreplace it fully. - For
@MethodSource, name the arguments method<testMethodName>Arguments(camelCase, e.g.testMethodArguments) and returnStream<Arguments>usingStream.of(...)andarguments(...)with static import. - Ensure parameterized test names are human-readable (i.e. no hashcodes); instead add a description string as the first
Arguments.arguments(...)value or index the test case - When converting tuples, create a light dedicated structure instead to keep the typing system
- Instead of checking a state and throwing an exception, use JUnit asserts
- Instead of using
assertTrue(a.equals(b))orassertFalse(a.equals(b)), useassertEquals(expected, actual)andassertNotEquals(unexpected, actual) - Import frequently used types rather than using fully-qualified names inline, to improve readability
- Do not wrap checked exceptions and throw a Runtime exception; prefer adding a throws clause at method declaration
- Do not mark local variables
final - Ensure variables are human-readable; avoid single-letter names and pre-define variables that are referenced multiple times
- When translating Spock
Mock(...)usage, uselibs.bundles.mockitoinstead of writing manual recording/stub implementations - Replace
injectSysConfig(key, value)calls with@WithConfigwhen the key and value are static literals. Put it on the test method for per-test config, or on the class when every test needs it. Thedd.prefix is added automatically — use the bare key (e.g."trace.scope.strict.mode", not"dd.trace.scope.strict.mode"). For dynamic or parameterized values, keep the imperativeWithConfigExtension.injectSysConfig(key, value)call. - Keep inline comments
- Migrate the named Spock clauses if they exist as inline comments in the Java unit test
- When Groovy tests navigate a JSON request body through helpers like
asMap()/asLong()/asList(), check whetherjson-unit-assertj(libs.json.unit.assertj) is already in the module's build file. If it is, add a method that returns the raw JSON string and useassertThatJson(json).node("some.nested.field").isEqualTo(value)directly instead of the map traversal. - Groovy's
[key: val]map literals use aLinkedHashMap. When the test doesn't care about insertion order, usesingletonMapfor a single entry orHashMapfor two or more. If a helper method builds these maps, add a two-arg overload rather than scatteringnew LinkedHashMap<>()constructions through test bodies. - The Spock construct
clean:section needs to wrap the unit test with a try...finally block to respect the behavior.
TableTest usage
Import: import org.tabletest.junit.TableTest;
JDK 8 rules:
- No text blocks.
- @TableTest must use String[] annotation array syntax:
@TableTest({
"a | b",
"1 | 2"
})
Spock where: → @TableTest:
- First row = header (column names = method parameters).
- Add scenario column as first column (display name, not a method parameter).
- Use | delimiter; align columns so pipes line up vertically.
- Prefer single quotes for strings with special chars (e.g., 'a|b', '[]').
- Blank cell = null (object types); '' = empty string.
- Collections: [a, b] = List/array, {a, b} = Set, [k: v] = Map.
Mixed eligibility:
- Prefer combining @TableTest + @MethodSource on one @ParameterizedTest when only some cases are complex.
- Use @MethodSource only when tabular representation is not practical for the test.
Do NOT use @TableTest when: - Majority of rows require complex objects or custom converters.
Quality rules (apply during generation)
Before writing any Java output, read .claude/skills/migrate-groovy-to-java/QUALITY_RULES.md in full.
Apply all BLOCKER rules unconditionally.
Apply WARNING rules unless they require creating utility classes that do not yet exist.
Apply STYLE rules where they improve clarity without added complexity.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

