Class AnnotatedTestExecutor
AnnotatedTestConfiguration,
dispatching beforeTest()/afterTest(boolean) to one of two path objects -
SetupTeardownLifecycle when AnnotatedTestConfiguration.isExpected() is false,
ExpectedLifecycle when it is true - and owning what both share: the one
TestScopedConnection this test's steps reuse, its ConnectionOwnership
decision, the @DbUnitProperty application, and (for an annotation-driven test) the
ExecutorOperationListener installed on the tester.
Not intended for direct use by test code; this is machinery consumed by a binding such as
DbUnitExtension, which resolves the IDatabaseTester and any injected
PrepAndExpectedTestCase - field discovery is binding-specific - and hands them here
already resolved.
The binding tells this executor, through the constructor's annotationDriven flag,
whether the test opted into the org.dbunit.annotation family at all - any
@DbUnit* annotation, or a @DbUnitTester/@DbUnitTestCase field. When it
did not - a bare @ExtendWith(DbUnitExtension.class) class with one plain, unannotated
IDatabaseTester field, the 3.5.0 lifecycle-only style - this executor takes the
classic path: installOperationListener() does not run, so the tester's
IOperationListener is left untouched, and AnnotatedRowCountCheck never
piggybacks (it captures its baseline eagerly and SetupTeardownLifecycle lets
onSetup()/onTearDown() manage their own connections) - exactly as
DbUnitExtension did before this class existed. The prep/expected path is always
annotation-driven (it needs @DbUnitExpected).
The connection getConnection() memoizes - the tester's own on the setup/teardown
path, PrepAndExpectedTestCase.getReusableConnection()'s on the prep/expected path so a
Connection/IDatabaseConnection parameter shares the test case's own - is used
by the row count check and by a binding's parameter injection, and closed in
afterTest(boolean) when ConnectionOwnership.mayClose() allows it. On an
annotation-driven test the ExecutorOperationListener additionally shields that one
connection, by identity, from a premature close by the tester's own onSetup()/
onTearDown() machinery while still forwarding a close for any other connection the
tester hands out.
The row count check (see org.dbunit.database.rowcount.RowCountCheck) runs, on the
setup/teardown path, through AnnotatedRowCountCheck; the prep/expected path already
has its own via DefaultPrepAndExpectedTestCase.preTest() and cleanupData().
Either way, when @DbUnitRowCountCheck is declared its resolved RowCountCheck
overrides whichever of the two would otherwise resolve one from the connection's own
DatabaseConfig - for the prep/expected path via
DefaultPrepAndExpectedTestCase.setRowCountCheckOverride(boolean, String[]) (applied
by InjectedTestCaseConfigurer), which resolves that connection lazily on its own so
this executor needs none just to build the override.
- Since:
- 3.6.0
- Author:
- Jeff Jensen
-
Constructor Summary
ConstructorsConstructorDescriptionAnnotatedTestExecutor(AnnotatedTestConfiguration configuration, IDatabaseTester tester, PrepAndExpectedTestCase prepAndExpectedTestCase) Creates an executor for an annotation-driven test - equivalent toAnnotatedTestExecutor(AnnotatedTestConfiguration, IDatabaseTester, PrepAndExpectedTestCase, boolean)withannotationDriventrue.AnnotatedTestExecutor(AnnotatedTestConfiguration configuration, IDatabaseTester tester, PrepAndExpectedTestCase prepAndExpectedTestCase, boolean annotationDriven) Creates an executor for one test. -
Method Summary
Modifier and TypeMethodDescriptionvoidafterTest(boolean testFailed) Runs every after-test step by delegating to the pathAnnotatedTestConfiguration.isExpected()selects -SetupTeardownLifecycle.after(boolean)orExpectedLifecycle.after(boolean)- then closes the connectiontestScopedConnectionmemoized, if one was ever resolved, so a difference reported by the row count check still leaves it closed.voidRuns every before-test step by delegating to the pathAnnotatedTestConfiguration.isExpected()selects:SetupTeardownLifecycle.before()orExpectedLifecycle.before().Returns the connection this test's steps use, resolved at most once per test and reused by every caller instead of each asking independently - the row count check's own baseline/verify calls on the setup/teardown path, and a binding injecting anIDatabaseConnection/Connectionparameter on either path.Returns thePrepAndExpectedTestCasethis executor drives, ornullwhenAnnotatedTestConfiguration.isExpected()is false, or it is true but nothing has constructed one yet - a binding resolving a parameter beforebeforeTest()runs (e.g. a@BeforeEachparameter) seesnullunless one was already injected through the constructor, or an earlier parameter resolution this same test already triggeredExpectedLifecycle.ensureTestCase()(e.g. aConnectionparameter resolved viagetConnection()).Returns the tester this executor drives, so a binding can inject it as a parameter without resolving a second, independent instance.
-
Constructor Details
-
AnnotatedTestExecutor
public AnnotatedTestExecutor(AnnotatedTestConfiguration configuration, IDatabaseTester tester, PrepAndExpectedTestCase prepAndExpectedTestCase) Creates an executor for an annotation-driven test - equivalent toAnnotatedTestExecutor(AnnotatedTestConfiguration, IDatabaseTester, PrepAndExpectedTestCase, boolean)withannotationDriventrue.- Parameters:
configuration- The resolved configuration to execute.tester- The tester to drive the setup/teardown path with, or to construct aPrepAndExpectedTestCasearound whenprepAndExpectedTestCaseisnulland the prep/expected path is configured.prepAndExpectedTestCase- An already-injected test case to drive instead of constructing one, ornullto have this executor construct one fromAnnotatedTestConfiguration.getPrepAndExpectedTestCaseClass().
-
AnnotatedTestExecutor
public AnnotatedTestExecutor(AnnotatedTestConfiguration configuration, IDatabaseTester tester, PrepAndExpectedTestCase prepAndExpectedTestCase, boolean annotationDriven) Creates an executor for one test.Mutates
testeronly whenannotationDrivenis true:installOperationListener()runs here, replacingtester'sIOperationListenerwith anExecutorOperationListenerwrapping the previous one. A binding constructs one executor per test method, so atestershared across methods (e.g. astatic @DbUnitTesterfield) is re-wrapped each time -ConnectionPreservingOperationListener.unwrap(IOperationListener)unwraps the prior wrapper first, so the layers do not stack - and the last test's wrapper stays installed on the tester after the class finishes, holding a reference to that last executor until the tester is itself discarded or given a new listener. WhenannotationDrivenis false - the classic path - the tester's listener is left untouched; see the class Javadoc.- Parameters:
configuration- The resolved configuration to execute.tester- The tester to drive the setup/teardown path with, or to construct aPrepAndExpectedTestCasearound whenprepAndExpectedTestCaseisnulland the prep/expected path is configured.prepAndExpectedTestCase- An already-injected test case to drive instead of constructing one, ornullto have this executor construct one fromAnnotatedTestConfiguration.getPrepAndExpectedTestCaseClass().annotationDriven- Whether the test opted into theorg.dbunit.annotationfamily - any@DbUnit*annotation, or a@DbUnitTester/@DbUnitTestCasefield. False for a bare@ExtendWith(DbUnitExtension.class)class with one plain, unannotatedIDatabaseTesterfield, whose tester listener and connection lifecycle are then left exactly as the 3.5.0 lifecycle. Always true for the prep/expected path, which needs@DbUnitExpected.
-
-
Method Details
-
getTester
Returns the tester this executor drives, so a binding can inject it as a parameter without resolving a second, independent instance.- Returns:
- The tester passed to the constructor.
-
getPrepAndExpectedTestCase
Returns thePrepAndExpectedTestCasethis executor drives, ornullwhenAnnotatedTestConfiguration.isExpected()is false, or it is true but nothing has constructed one yet - a binding resolving a parameter beforebeforeTest()runs (e.g. a@BeforeEachparameter) seesnullunless one was already injected through the constructor, or an earlier parameter resolution this same test already triggeredExpectedLifecycle.ensureTestCase()(e.g. aConnectionparameter resolved viagetConnection()).- Returns:
- The test case this executor drives, or
nullif none exists yet.
-
getConnection
Returns the connection this test's steps use, resolved at most once per test and reused by every caller instead of each asking independently - the row count check's own baseline/verify calls on the setup/teardown path, and a binding injecting anIDatabaseConnection/Connectionparameter on either path. On the prep/expected path (AnnotatedTestConfiguration.isExpected()true), delegates toPrepAndExpectedTestCase.getReusableConnection()- constructing the test case first viaExpectedLifecycle.ensureTestCase()if it does not exist yet - instead of askingtesterdirectly, so a parameter injection shares that test case's own connection; on the setup/teardown path, askstesterdirectly. For a tester with no connection caching of its own (e.g. a plainJdbcDatabaseTester), asking independently on either path would otherwise open one new physical connection per call. Closed inafterTest(boolean)- see the class Javadoc.- Returns:
- The connection to reuse, or
nullif none is available (e.g. a test double). - Throws:
Exception- If resolving the connection fails.
-
beforeTest
Runs every before-test step by delegating to the pathAnnotatedTestConfiguration.isExpected()selects:SetupTeardownLifecycle.before()orExpectedLifecycle.before().- Throws:
Exception- If any step fails.
-
afterTest
Runs every after-test step by delegating to the pathAnnotatedTestConfiguration.isExpected()selects -SetupTeardownLifecycle.after(boolean)orExpectedLifecycle.after(boolean)- then closes the connectiontestScopedConnectionmemoized, if one was ever resolved, so a difference reported by the row count check still leaves it closed.When both the step and closing the connection fail, the step's failure is the one thrown, with the close failure attached to it via
Throwable.addSuppressed(Throwable)rather than replacing it - a plainfinallyblock would otherwise let the close failure silently discard the more useful diagnostic (e.g. which table the row count check found unexpectedly changed). The step's failure is caught asThrowable, not justException, and rethrown with its original static type preserved: a comparison mismatch on the prep/expected path fails viaDbComparisonFailure, anErrorsubclass, not anException- catching onlyExceptionwould skip closing the connection on every ordinary verification failure, the single most common way this method's step throws at all.
-