Skip to main content

Methods Annotated with @BeforeTransaction or @AfterTransaction Must Respect the Contract

High
correctnesserror-handling

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
}
}