Skip to content

feat(junit5): Add DbUnitExtension for JUnit 5/6 lifecycle management - #912

Merged
jeffjensen merged 1 commit into
mainfrom
feat/junit5-extension
Aug 7, 2026
Merged

jeffjensen merged 1 commit into
mainfrom
feat/junit5-extension

Conversation

@jeffjensen

@jeffjensen jeffjensen commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

  • Add DbUnitExtension, a JUnit 5/6 extension that wires IDatabaseTester into the test lifecycle via BeforeTestExecutionCallback and AfterTestExecutionCallback.
  • The extension discovers the IDatabaseTester by scanning instance fields (including inherited), so test classes configure their tester in @BeforeEach and annotate with @ExtendWith(DbUnitExtension.class) rather than extending DatabaseTestCase.

Fixes #751

Test plan

  • ./mvnw clean test — full unit test suite passes (1985 tests, 0 failures)
  • ./mvnw clean install site — builds and site generation succeed

🤖 Generated with Claude Code

https://claude.ai/code/session_015h89ycy4uviGgM4tUBdarR

Summary by CodeRabbit

  • New Features

    • Added JUnit 5/6 integration that automatically runs database test setup and teardown around each test.
    • Supports composition-based tests without requiring DatabaseTestCase inheritance.
    • Detects configured testers across inherited test classes and validates ambiguous or missing configurations.
  • Documentation

    • Added usage guidance, lifecycle behavior, configuration rules, and navigation for the new integration.
  • Tests

    • Added coverage for lifecycle ordering, failures, inheritance, validation, and exception handling.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sourcery-ai

sourcery-ai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a new JUnit 5/6 DbUnitExtension that discovers an IDatabaseTester field on the test instance, runs its onSetup/onTearDown around each test method using JUnit’s BeforeTestExecutionCallback/AfterTestExecutionCallback hooks, and adds tests plus build metadata and dependencies to validate lifecycle ordering and error handling.

Sequence diagram for DbUnitExtension test lifecycle management

sequenceDiagram
    participant JUnitEngine
    participant DbUnitExtension
    participant ExtensionContext
    participant TestInstance
    participant IDatabaseTester

    JUnitEngine->>DbUnitExtension: beforeTestExecution(ExtensionContext)
    DbUnitExtension->>ExtensionContext: getTestInstance()
    ExtensionContext-->>DbUnitExtension: Optional[TestInstance]
    DbUnitExtension->>DbUnitExtension: resolveTester(ExtensionContext)
    DbUnitExtension->>TestInstance: access IDatabaseTester field
    TestInstance-->>DbUnitExtension: IDatabaseTester
    DbUnitExtension->>ExtensionContext: getStore(NAMESPACE).put(TESTER_KEY, tester)
    DbUnitExtension->>IDatabaseTester: onSetup()
    DbUnitExtension-->>JUnitEngine: 

    JUnitEngine->>DbUnitExtension: afterTestExecution(ExtensionContext)
    DbUnitExtension->>ExtensionContext: getStore(NAMESPACE).get(TESTER_KEY, IDatabaseTester)
    ExtensionContext-->>DbUnitExtension: IDatabaseTester
    DbUnitExtension->>IDatabaseTester: onTearDown()
    DbUnitExtension-->>JUnitEngine:
Loading

File-Level Changes

Change Details Files
Add DbUnitExtension JUnit 5/6 extension that manages IDatabaseTester lifecycle around each test method via field discovery.
  • Implement DbUnitExtension implementing BeforeTestExecutionCallback and AfterTestExecutionCallback, resolving a non-static IDatabaseTester field (including in superclasses) on the test instance and storing it in an ExtensionContext.Namespace-scoped Store.
  • Invoke IDatabaseTester.onSetup() in beforeTestExecution after resolving and storing the tester, and IDatabaseTester.onTearDown() in afterTestExecution if a tester was stored.
  • Perform reflective scan of declared fields from the concrete test class up its superclass chain, preferring subclass fields over superclass ones, skipping static fields, erroring if no tester field is found or if the resolved field value is null, and logging the resolved field name at debug level.
src/main/java/org/dbunit/junit5/DbUnitExtension.java
Add focused unit and integration-style lifecycle tests for DbUnitExtension, including EngineTestKit-based verification of call ordering and teardown-on-failure semantics.
  • Add DbUnitExtensionTest using Mockito to verify beforeTestExecution behavior (field discovery, superclass precedence, error cases, and exception propagation) and afterTestExecution behavior (conditional onTearDown invocation and exception propagation).
  • Introduce helper inner classes in DbUnitExtensionTest to simulate various field configurations (private tester, inherited tester, multiple testers with subclass precedence, static-only testers).
  • Add DbUnitExtensionLifecycleTest using JUnit Platform EngineTestKit and sample test classes to assert precise ordering of @beforeeach, onSetup, test method, and onTearDown, and to verify that onTearDown is still called when the test method fails, using a CallLoggingTester implementation of IDatabaseTester.
src/test/java/org/dbunit/junit5/DbUnitExtensionTest.java
src/test/java/org/dbunit/junit5/DbUnitExtensionLifecycleTest.java
Wire in JUnit Platform Test Kit dependency and document the new extension in the project change log.
  • Add junit-platform-testkit dependency aligned with junitVersion in the main dependency management and as a test-scoped dependency in the module where tests run.
  • Update changes.xml release description to mention the new JUnit 5/6 DbUnitExtension module and add corresponding change-log actions referencing the implementing issue numbers.
  • Ensure the new extension and tests integrate with the existing build by relying on mvnw clean test/install workflows described in the PR description.
pom.xml
src/changes/changes.xml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f2eddc96-7851-4c30-a672-f06bc5c4af66

📥 Commits

Reviewing files that changed from the base of the PR and between daa8dcd and 13371a3.

📒 Files selected for processing (10)
  • CLAUDE.md
  • pom.xml
  • src/changes/changes.xml
  • src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java
  • src/site/asciidoc/testcases.adoc
  • src/site/asciidoc/testcases/DbUnitExtension.adoc
  • src/site/asciidoc/testcases/IDatabaseTester.adoc
  • src/site/site.xml
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java
🚧 Files skipped from review as they are similar to previous changes (9)
  • pom.xml
  • src/changes/changes.xml
  • src/site/asciidoc/testcases.adoc
  • src/site/site.xml
  • src/site/asciidoc/testcases/DbUnitExtension.adoc
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java
  • src/site/asciidoc/testcases/IDatabaseTester.adoc
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java
  • CLAUDE.md

📝 Walkthrough

Walkthrough

Changes

JUnit DbUnit extension lifecycle

Layer / File(s) Summary
Extension discovery and lifecycle
src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java, pom.xml
Added DbUnitExtension with hierarchy-aware IDatabaseTester discovery, field validation, extension-store state, and setup/teardown callbacks. Added JUnit Platform Testkit dependency management.
Discovery and callback validation
src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java
Added Mockito tests for visibility, inheritance, precedence, invalid fields, callback invocation, state storage, and exception propagation.
Engine lifecycle integration
src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java
Added EngineTestKit tests for callback ordering and teardown after test-method or setup failures.
Documentation and release wiring
CLAUDE.md, src/changes/changes.xml, src/site/asciidoc/testcases.adoc, src/site/asciidoc/testcases/DbUnitExtension.adoc, src/site/asciidoc/testcases/IDatabaseTester.adoc, src/site/site.xml
Documented the extension, added site navigation, and updated the 3.4.1-SNAPSHOT release metadata.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant JUnit as JUnit test execution
  participant DbUnitExtension
  participant TestInstance
  participant IDatabaseTester
  JUnit->>DbUnitExtension: beforeTestExecution
  DbUnitExtension->>TestInstance: resolve IDatabaseTester field
  TestInstance-->>DbUnitExtension: IDatabaseTester
  DbUnitExtension->>IDatabaseTester: onSetup
  JUnit->>DbUnitExtension: afterTestExecution
  DbUnitExtension->>IDatabaseTester: onTearDown
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the added DbUnitExtension and its JUnit 5/6 lifecycle purpose.
Linked Issues check ✅ Passed The implementation adds the JUnit 5/6 extension module for @ExtendWith, including lifecycle handling, tests, dependencies, and documentation [#751].
Out of Scope Changes check ✅ Passed The dependency, implementation, tests, documentation, navigation, and changelog changes directly support the linked extension objective.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/junit5-extension

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • The new DbUnitExtension is annotated with @since 3.2.0 but the change is recorded under the 3.4.1-SNAPSHOT release in changes.xml; align the @since tag with the actual version this is introduced in.
  • changes.xml now contains two separate <action> entries describing the addition of DbUnitExtension (issues 751 and TBD, in different releases); consider consolidating or removing the duplicate so the changelog reflects a single, accurate entry.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new DbUnitExtension is annotated with `@since 3.2.0` but the change is recorded under the 3.4.1-SNAPSHOT release in changes.xml; align the `@since` tag with the actual version this is introduced in.
- changes.xml now contains two separate `<action>` entries describing the addition of DbUnitExtension (issues 751 and TBD, in different releases); consider consolidating or removing the duplicate so the changelog reflects a single, accurate entry.

## Individual Comments

### Comment 1
<location path="src/main/java/org/dbunit/junit5/DbUnitExtension.java" line_range="114-117" />
<code_context>
+            clazz = clazz.getSuperclass();
+        }
+
+        throw new IllegalStateException("No IDatabaseTester field found in "
+                + testInstance.getClass().getName()
+                + " or its superclasses. Declare a non-static field of type IDatabaseTester"
+                + " to use DbUnitExtension.");
+    }
+}
</code_context>
<issue_to_address>
**nitpick (typo):** Error message could be clearer about accepting IDatabaseTester subtypes, not just the raw interface.

Since the resolution logic uses `IDatabaseTester.class.isAssignableFrom(field.getType())`, it also accepts subclasses/implementations. The current wording (“field of type IDatabaseTester”) could confuse users with a custom `MyDatabaseTester extends IDatabaseTester`. Consider rephrasing to “Declare a non-static field whose type implements IDatabaseTester” to reflect the actual behavior.

```suggestion
        throw new IllegalStateException("No IDatabaseTester field found in "
                + testInstance.getClass().getName()
                + " or its superclasses. Declare a non-static field whose type implements IDatabaseTester"
                + " to use DbUnitExtension.");
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/test/java/org/dbunit/junit5/DbUnitExtensionLifecycleTest.java (1)

48-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename the lifecycle test methods to state condition and outcome.

Use names such as testBeforeAndAfterTestExecution_testMethodSucceeds_callbacksRunInOrder and testAfterTestExecution_testMethodFails_onTearDownCalled.

As per coding guidelines, “use method names in the form test<MethodName>_<StartingStateConditions>_<AssertedOutcome>.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/dbunit/junit5/DbUnitExtensionLifecycleTest.java` around
lines 48 - 69, Rename the two lifecycle test methods to follow the
test<MethodName>_<StartingStateConditions>_<AssertedOutcome> convention: use
testBeforeAndAfterTestExecution_testMethodSucceeds_callbacksRunInOrder for the
successful lifecycle-order test and
testAfterTestExecution_testMethodFails_onTearDownCalled for the failing-test
cleanup case.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/changes/changes.xml`:
- Line 543: Correct the release attribution for DbUnitExtension: remove its
historical 3.2.0 action, including issue="TBD", from src/changes/changes.xml
lines 543-543; remove the historical 3.4.0 action from src/changes/changes.xml
lines 511-513; and update the DbUnitExtension `@since` tag in
src/main/java/org/dbunit/junit5/DbUnitExtension.java line 63 to 3.4.1.

In `@src/main/java/org/dbunit/junit5/DbUnitExtension.java`:
- Around line 73-87: Add complete JavaDoc to the public callback methods
beforeTestExecution and afterTestExecution in DbUnitExtension, including a
capitalized, period-terminated summary, a `@param` description for context, and a
`@throws` description for Exception.
- Around line 96-109: Update resolveTester() to collect non-static fields
assignable to IDatabaseTester in the nearest class, reject the case where more
than one matches with a clear IllegalStateException, and retain the existing
null validation and tester return for exactly one match. Add a test covering a
class with multiple IDatabaseTester fields and asserting the rejection.

---

Nitpick comments:
In `@src/test/java/org/dbunit/junit5/DbUnitExtensionLifecycleTest.java`:
- Around line 48-69: Rename the two lifecycle test methods to follow the
test<MethodName>_<StartingStateConditions>_<AssertedOutcome> convention: use
testBeforeAndAfterTestExecution_testMethodSucceeds_callbacksRunInOrder for the
successful lifecycle-order test and
testAfterTestExecution_testMethodFails_onTearDownCalled for the failing-test
cleanup case.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9bcdf0a7-8c29-435d-96e0-3fe56a6bb896

📥 Commits

Reviewing files that changed from the base of the PR and between daa8dcd and 18a83a3.

📒 Files selected for processing (5)
  • pom.xml
  • src/changes/changes.xml
  • src/main/java/org/dbunit/junit5/DbUnitExtension.java
  • src/test/java/org/dbunit/junit5/DbUnitExtensionLifecycleTest.java
  • src/test/java/org/dbunit/junit5/DbUnitExtensionTest.java

Comment thread src/changes/changes.xml Outdated
Comment thread src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java
Comment thread src/main/java/org/dbunit/junit5/DbUnitExtension.java Outdated
@jeffjensen
jeffjensen force-pushed the feat/junit5-extension branch 2 times, most recently from ffce9ef to 76cffa9 Compare August 6, 2026 21:08
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java (1)

195-203: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Strengthen the no-stored-tester assertion.

The store returns null, so databaseTester can never receive onTearDown(). The never() check therefore always passes. Use verifyNoInteractions(databaseTester) to state the intent, or assert that afterTestExecution completes without an exception.

Proposed change
-        verify(databaseTester, never()).onTearDown();
+        verifyNoInteractions(databaseTester);

Add the import:

import static org.mockito.Mockito.verifyNoInteractions;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java` around lines
195 - 203, Strengthen
testAfterTestExecution_noStoredTester_doesNotCallOnTearDown by replacing the
ineffective verify(databaseTester, never()) assertion with
verifyNoInteractions(databaseTester), adding the corresponding Mockito static
import.
src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java (2)

46-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the blank line after the opening brace.

Proposed fix
 class DbUnitExtensionLifecycleTest {
-
     `@Test`

As per coding guidelines, "Do not leave a blank line immediately after an opening curly brace."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java`
around lines 46 - 47, Remove the blank line immediately after the opening brace
of the DbUnitExtensionLifecycleTest class, leaving the class declaration
directly followed by its first member or statement.

Source: Coding guidelines


126-127: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Static CALL_LOG fields couple the sample classes to the outer test methods.

FailingTestSample.CALL_LOG and FailingSetupSample.CALL_LOG hold state across executions. The outer methods clear each list before EngineTestKit runs. If the project later enables JUnit parallel execution for this class, the clear-then-assert sequence becomes order dependent, even though the lists are synchronized.

LifecycleOrderSample avoids this problem by asserting inside the sample class with an instance list. Consider the same approach for the two failure samples, or annotate this class with @Execution(SAME_THREAD).

This is optional. The current tests are correct under sequential execution.

Also applies to: 142-143

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java`
around lines 126 - 127, Remove the static CALL_LOG state from FailingTestSample
and FailingSetupSample to avoid cross-execution coupling. Use instance-owned
logs and perform lifecycle assertions inside each sample, matching
LifecycleOrderSample; alternatively, annotate the enclosing test class with
`@Execution`(SAME_THREAD) to preserve the clear-then-assert ordering.
src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java (2)

108-135: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider supporting @Nested test classes through getRequiredTestInstances().

resolveTester only scans the innermost test instance and its superclasses. The class JavaDoc documents this limitation. JUnit Jupiter exposes ExtensionContext.getTestInstances(), which returns all enclosing instances for @Nested classes. You can scan those instances from innermost to outermost and remove the limitation.

This is optional. The current behavior is documented and fails with a clear message.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java` around lines 108
- 135, Optionally update resolveTester to use
ExtensionContext.getTestInstances() and scan all enclosing `@Nested` test
instances from innermost to outermost, applying the existing field lookup and
null validation to each instance. Remove or revise the JavaDoc and failure
message that state only the innermost instance and its superclasses are
supported.

137-152: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

findTesterField mixes lookup and message formatting.

The testInstance parameter is used only to build the exception message. The method name states field lookup. Consider moving the ambiguity check message to the caller, or rename the method to state both duties.

This is a small clarity point. The behavior is correct.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java` around lines 137
- 152, Refactor findTesterField so field lookup and ambiguity-message
construction are separated: remove the testInstance dependency from the lookup
method and move the multiple-field exception formatting to its caller, or rename
the method to explicitly reflect both responsibilities. Preserve the existing
ambiguity validation and exception message behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/site/asciidoc/testcases/IDatabaseTester.adoc`:
- Around line 103-106: Update the DbUnitExtension tip to clarify that it
replaces only the manual onSetup() and onTearDown() calls, not the entire
configuration hook. In the example around the `@BeforeEach/`@AfterEach pair,
instruct users to retain `@BeforeEach` when it configures the tester with the
dataset and teardown operation.

---

Nitpick comments:
In `@src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java`:
- Around line 108-135: Optionally update resolveTester to use
ExtensionContext.getTestInstances() and scan all enclosing `@Nested` test
instances from innermost to outermost, applying the existing field lookup and
null validation to each instance. Remove or revise the JavaDoc and failure
message that state only the innermost instance and its superclasses are
supported.
- Around line 137-152: Refactor findTesterField so field lookup and
ambiguity-message construction are separated: remove the testInstance dependency
from the lookup method and move the multiple-field exception formatting to its
caller, or rename the method to explicitly reflect both responsibilities.
Preserve the existing ambiguity validation and exception message behavior.

In `@src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java`:
- Around line 46-47: Remove the blank line immediately after the opening brace
of the DbUnitExtensionLifecycleTest class, leaving the class declaration
directly followed by its first member or statement.
- Around line 126-127: Remove the static CALL_LOG state from FailingTestSample
and FailingSetupSample to avoid cross-execution coupling. Use instance-owned
logs and perform lifecycle assertions inside each sample, matching
LifecycleOrderSample; alternatively, annotate the enclosing test class with
`@Execution`(SAME_THREAD) to preserve the clear-then-assert ordering.

In `@src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java`:
- Around line 195-203: Strengthen
testAfterTestExecution_noStoredTester_doesNotCallOnTearDown by replacing the
ineffective verify(databaseTester, never()) assertion with
verifyNoInteractions(databaseTester), adding the corresponding Mockito static
import.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cbeb13ab-c397-4f84-bc2e-ecde3cdee2ce

📥 Commits

Reviewing files that changed from the base of the PR and between daa8dcd and 76cffa9.

📒 Files selected for processing (10)
  • CLAUDE.md
  • pom.xml
  • src/changes/changes.xml
  • src/main/java/org/dbunit/junit/jupiter/DbUnitExtension.java
  • src/site/asciidoc/testcases.adoc
  • src/site/asciidoc/testcases/DbUnitExtension.adoc
  • src/site/asciidoc/testcases/IDatabaseTester.adoc
  • src/site/site.xml
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionLifecycleTest.java
  • src/test/java/org/dbunit/junit/jupiter/DbUnitExtensionTest.java
🚧 Files skipped from review as they are similar to previous changes (2)
  • pom.xml
  • src/changes/changes.xml

Comment thread src/site/asciidoc/testcases/IDatabaseTester.adoc
Add DbUnitExtension, a JUnit 5/6 extension that wires IDatabaseTester
into the test lifecycle via BeforeTestExecutionCallback and
AfterTestExecutionCallback. The extension discovers the IDatabaseTester
by scanning instance fields (including inherited), so test classes
configure their tester in @beforeeach and annotate with
@ExtendWith(DbUnitExtension.class) rather than extending
DatabaseTestCase.

Package the extension as org.dbunit.junit.jupiter, mirroring JUnit's
own org.junit.jupiter namespace, rather than org.dbunit.junit5: JUnit 6
kept the Jupiter programming model and its org.junit.jupiter.* API
package unchanged from JUnit 5 (dbUnit itself now builds and tests
against JUnit 6), so "jupiter" stays accurate across major versions
where a version-numbered package name would not.

Reject a test class that declares more than one non-static
IDatabaseTester-assignable field at the same class level instead of
silently using Class#getDeclaredFields()'s undefined iteration order,
and cover the case with a test. Add an EngineTestKit lifecycle test
verifying onTearDown() still runs (and the test method itself never
executes) when onSetup() throws. Document the @nested limitation and
the field-ambiguity rejection in the class Javadoc. Add the
testcases/DbUnitExtension.adoc site page, cross-linked from
testcases.adoc and testcases/IDatabaseTester.adoc, and list the new
org.dbunit.junit.jupiter package in CLAUDE.md's package structure.

Clarify the IDatabaseTester.adoc TIP on DbUnitExtension: it only
automates the onSetup()/onTearDown() calls, not tester configuration,
so tell readers to keep @beforeeach when it still configures the
tester (e.g. setDataSet()/setTearDownOperation()) instead of implying
the whole method can be deleted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Refs: 751
@jeffjensen
jeffjensen force-pushed the feat/junit5-extension branch from 76cffa9 to 13371a3 Compare August 7, 2026 00:11
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@jeffjensen
jeffjensen merged commit f6a3ef5 into main Aug 7, 2026
27 checks passed
@jeffjensen
jeffjensen deleted the feat/junit5-extension branch August 7, 2026 00:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add JUnit 5/6 extension module for @ExtendWith

1 participant