GH-150 - Scenario now execute stimulus within new transaction.
To make sure that we trigger transactional event listeners from Scenario based integration tests, we trigger stimulus executions using transactions configured to require a new transaction. This makes sure that Scenarios work in integration tests using @Transactional, of course circumventing the default rollback behavior of those transactions. There's no other way to implement this as we *need* to commit a transaction to trigger the delivery of transaction-bound events. Fixed a bug in the handling of Scenario.stimulus(Supplier<T>) as for this, the Supplier handed into the method had not been executed transactionally at all.
This commit is contained in:
@@ -34,7 +34,10 @@ import org.springframework.modulith.test.PublishedEvents.TypedPublishedEvents;
|
||||
import org.springframework.modulith.test.PublishedEventsAssert.PublishedEventAssert;
|
||||
import org.springframework.modulith.test.Scenario.When.EventResult;
|
||||
import org.springframework.modulith.test.Scenario.When.StateChangeResult;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionOperations;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.tngtech.archunit.thirdparty.com.google.common.base.Optional;
|
||||
@@ -72,21 +75,24 @@ public class Scenario {
|
||||
private final AssertablePublishedEvents events;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Scenario} for the given {@link TransactionOperations}, {@link ApplicationEventPublisher} and
|
||||
* Creates a new {@link Scenario} for the given {@link TransactionTemplate}, {@link ApplicationEventPublisher} and
|
||||
* {@link AssertablePublishedEvents}.
|
||||
*
|
||||
* @param transactionOperations must not be {@literal null}.
|
||||
* @param transactionTemplate must not be {@literal null}.
|
||||
* @param publisher must not be {@literal null}.
|
||||
* @param events must not be {@literal null}.
|
||||
*/
|
||||
Scenario(TransactionOperations transactionOperations, ApplicationEventPublisher publisher,
|
||||
Scenario(TransactionTemplate transactionTemplate, ApplicationEventPublisher publisher,
|
||||
AssertablePublishedEvents events) {
|
||||
|
||||
Assert.notNull(transactionOperations, "TransactionOperations must not be null!");
|
||||
Assert.notNull(transactionTemplate, "TransactionTemplate must not be null!");
|
||||
Assert.notNull(publisher, "ApplicationEventPublisher must not be null!");
|
||||
Assert.notNull(events, "AssertablePublishedEvents must not be null!");
|
||||
|
||||
this.transactionOperations = transactionOperations;
|
||||
var definition = new DefaultTransactionDefinition(transactionTemplate);
|
||||
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
|
||||
this.transactionOperations = new TransactionTemplate(transactionTemplate.getTransactionManager(), definition);
|
||||
this.publisher = publisher;
|
||||
this.events = events;
|
||||
}
|
||||
@@ -145,7 +151,7 @@ public class Scenario {
|
||||
* @see EventResult#toArriveAndVerify(Consumer)
|
||||
*/
|
||||
public <S> When<S> stimulate(Supplier<S> supplier) {
|
||||
return stimulate(__ -> supplier.get());
|
||||
return stimulate(tx -> tx.execute(__ -> supplier.get()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.extension.ParameterContext;
|
||||
import org.junit.jupiter.api.extension.ParameterResolutionException;
|
||||
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.transaction.support.TransactionOperations;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* JUnit {@link ParameterResolver} for {@link Scenario}.
|
||||
@@ -70,7 +70,7 @@ class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback
|
||||
throws ParameterResolutionException {
|
||||
|
||||
var context = SpringExtension.getApplicationContext(extensionContext);
|
||||
var operations = context.getBean(TransactionOperations.class);
|
||||
var operations = context.getBean(TransactionTemplate.class);
|
||||
var events = (AssertablePublishedEvents) delegate.resolveParameter(parameterContext, extensionContext);
|
||||
|
||||
return new Scenario(operations, context, events);
|
||||
|
||||
Reference in New Issue
Block a user