Ccodemod

codemod/junit4-spring-base-to-jupiter-annotations

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.

upgradespringjunitspring-testv7
Public
0 executions

Run locally

npx codemod @codemod/junit4-spring-base-to-jupiter-annotations

@codemod/junit4-spring-base-to-jupiter-annotations

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

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:

  • org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
  • org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests

For each matching class, the codemod:

  • 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

License

MIT

Ready to contribute?

Build your own codemod and share it with the community.