Methods Annotated with @BeforeTransaction
or @AfterTransaction
Must Respect the Contract
What is it?
This practice requires that methods annotated with @BeforeTransaction
or @AfterTransaction
in Spring's @Transactional
configured tests must be void and have no arguments.
Why apply it?
Deviating from this contract by having a non-void return type or accepting arguments will cause Spring to throw a runtime error, disrupting the proper execution of transactional operations within tests.
How to fix it?
Ensure that methods annotated with @BeforeTransaction
or @AfterTransaction
have a void return type and do not accept any arguments.
Examples
Example 1:
Negative
The negative example fails because the annotated methods do not return void and have arguments, violating the method contract.
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class TransactionalTest {
@BeforeTransaction
public String setupTransaction(int x) { // Noncompliant
// Setup logic
}
@AfterTransaction
public int cleanupTransaction(int x) { // Noncompliant
// Cleanup logic
}
}
Example 2:
Positive
The positive example correctly defines @BeforeTransaction
and @AfterTransaction
methods with a void return type and no arguments.
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class TransactionalTest {
@BeforeTransaction
public void setupTransaction() { // Compliant
// Setup logic
}
@AfterTransaction
public void cleanupTransaction() { // Compliant
// Cleanup logic
}
}
Negative
This negative example incorrectly implements @BeforeTransaction
and @AfterTransaction
methods by providing arguments and returning non-void values.
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class BatchProcessingTest {
@BeforeTransaction
public String initializeDatabase(boolean flag) { // Noncompliant
// Initialize db
}
@AfterTransaction
public int verifyDatabaseState(boolean flag) { // Noncompliant
// Verify db
}
}
Example 3:
Positive
The positive example adheres to the required contract for @BeforeTransaction
and @AfterTransaction
methods by having the correct return type and no parameters.
import org.springframework.test.context.transaction.BeforeTransaction;
import org.springframework.test.context.transaction.AfterTransaction;
import org.springframework.transaction.annotation.Transactional;
@Transactional
public class BatchProcessingTest {
@BeforeTransaction
public void initializeDatabase() { // Compliant
// Initialize db
}
@AfterTransaction
public void verifyDatabaseState() { // Compliant
// Verify db
}
}