Migrate Java Spring tests that extend `AbstractJUnit4SpringContextTests` or `AbstractTransactionalJUnit4SpringContextTests` to the Spring Framework 7 preferred JUnit Jupiter style by removing the deprecated base class inheritance and adding `@ExtendWith(SpringExtension.class)` plus `@Transactional` where required.
Migrate Java Spring tests that extend AbstractJUnit4SpringContextTests or AbstractTransactionalJUnit4SpringContextTests to the Spring Framework 7 preferred JUnit Jupiter style by removing the deprecated base class inheritance and adding @ExtendWith(SpringExtension.class) plus @Transactional where required.
Installation
bash
# Run locally against a target repository
pnpm dlx codemod@latest workflow run -w workflow.yaml --target <path-to-repo>
Usage
This codemod targets Java files in common test source sets:
src/test/java/**
src/integrationTest/java/**
src/*Test/java/**
It rewrites direct inheritance from these deprecated Spring JUnit 4 base classes:
Removes the direct extends clause for the deprecated base class
Adds @ExtendWith(SpringExtension.class) when it is missing
Appends SpringExtension.class to an existing class-level @ExtendWith(...) when needed
Adds class-level @Transactional for the transactional base class when it is missing
Removes exact imports for the deprecated base classes when the transformed file no longer needs them
Adds imports for ExtendWith, SpringExtension, and Transactional as needed
Preserve and no-op behavior:
Existing Spring test annotations such as @ContextConfiguration are preserved
Existing @ExtendWith(SpringExtension.class) or @Extensions(...) containers that already include SpringExtension are preserved without duplication
Classes in non-test source sets are left unchanged
Classes that still use @RunWith(SpringRunner.class) or @RunWith(SpringJUnit4ClassRunner.class) are intentionally left unchanged
Classes that only extend a project-local subclass are left unchanged because they do not directly extend the deprecated Spring base class
Limitations:
Java semantic type resolution is not available here, so simple-name matches are only rewritten when they are backed by a direct import, wildcard import from org.springframework.test.context.junit4.*, or a fully qualified superclass name
Wildcard imports from org.springframework.test.context.junit4.* are preserved to avoid removing unrelated JUnit 4 support types without full usage analysis
Development
bash
# Test the transformation
pnpm test
# Validate the package surface
pnpm dlx codemod@latest workflow validate -w workflow.yaml
# Publish to registry
pnpm dlx codemod@latest login
pnpm dlx codemod@latest publish
License
MIT
Ready to evolve your codebase?
Build tailored, compiler-aware skills to assess, plan, and automate complex codebase changes.