Skip to content

Support programmatic starting and stopping of transactions in the TestContext framework [SPR-5079] #9753

Closed
@spring-projects-issues

Description

@spring-projects-issues

Den Orlov opened SPR-5079 and commented

Background

I have integration tests that:

  1. put some test data into database using Hibernate
  2. wait some time, so DB stored procedures triggered by scheduler will process my data
  3. retrieve from db some data and check its correctness, again using Hibernate

When I used Spring's "JUnit 3.8 legacy support" all of these three steps were organized in one test method using the protected endTransaction() and startNewTransaction() methods in AbstractTransactionalSpringContextTests between steps #1 and #2.


Status Quo

Now I am migrating my code to use the Spring TestContext Framework (TCF), but it doesn't provide support for programmatically starting or stopping the test-managed transaction.


Deliverables

The term test-manged means a transaction managed by the TCF, either declaratively or programmatically.

See also "Design Considerations" below.

  1. Introduce a mechanism in the TCF that supports the following features:
    1. end the current test-managed transaction
    2. start a new test-managed transaction
    3. configure the current test-managed transaction to be committed once the test completes
    4. configure the current test-managed transaction to be rolled back once the test completes
  2. Refactor TransactionalTestExecutionListener to use this new mechanism internally.
  3. Consider introducing a JUnit TestRule that simplifies the programming model (e.g., by delegating to the proposed TestTransaction façade).

Design Considerations

Introduce a TestTransaction class that acts as a façade to the functionality previously available in TransactionalTestExecutionListener. For example, TestTransaction could define methods that could provide the following API:

  • TestTransaction.start()
  • TestTransaction.end()
  • TestTransaction.rollback(boolean)
Options for Interacting with the Test Transaction
Dependency Injection of TestTransaction

Ideally, we would like to be able to have the TestTransaction injected into our test instance. However, since the DependencyInjectionTestExecutionListener must come before the TransactionalTestExecutionListener in the chain of listeners, dependency injection would only be possible by introducing yet another "transactional" TestExecutionListener that creates a proxy bean or bean of type ObjectFactory in the ApplicationContext. Such a proxy bean would serve as a placeholder for dependency injection into the test instance, and the TransactionalTestExecutionListener could later set a value either directly in the proxy/ObjectFactory or via a ThreadLocal.

But we would like to avoid having two (2) TestExecutionListener implementations for transactional support. Plus, the placeholder-bean approach could present more problems than it solves.

Dependency Injection of TestContext

A second option would be to inject the TestContext into test instances (see #12947) and provide access to the TestTransaction as an attribute (note that TestContext implements AttributeAccessor), but this would open up use of the TestContext within test classes (i.e., no longer limited to the TestExecutionListener API). In addition, developers would be forced to navigate the TestContext to obtain the TestTransaction, thus making the programming model less intuitive.

Purely ThreadLocal Approach

The final option is to follow a purely ThreadLocal-based approach with TestTransaction encapsulating the details and providing static methods instead of instance methods.


Related Resources


Affects: 2.5.6

Issue Links:

Referenced from: commits bdceaa4, f667e43, 90f0d14

30 votes, 22 watchers

Metadata

Metadata

Assignees

Labels

has: votes-jiraIssues migrated from JIRA with more than 10 votes at the time of importin: testIssues in the test moduletype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions