GH-1131 - Non-empty collections do not indicate scenario completion anymore.

Similarly to our treatment of Optional, we now only consider non-empty collections a trigger for a state change based Scenario conclusion.
This commit is contained in:
Oliver Drotbohm
2025-03-28 12:50:46 +01:00
parent fa946c148b
commit 777a5c9e7e
2 changed files with 58 additions and 2 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.modulith.test;
import static org.assertj.core.api.Assertions.*;
import java.time.Duration;
import java.util.Collection;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.BiConsumer;
@@ -34,8 +35,6 @@ import org.springframework.lang.Nullable;
import org.springframework.modulith.core.util.CheckReturnValue;
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;
@@ -63,6 +62,10 @@ public class Scenario {
return o.isPresent();
}
if (it instanceof Collection<?> c) {
return !c.isEmpty();
}
if (it instanceof Boolean b) {
return b;
}

View File

@@ -23,7 +23,9 @@ import lombok.RequiredArgsConstructor;
import java.lang.Thread.UncaughtExceptionHandler;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -433,6 +435,57 @@ class ScenarioUnitTests {
verify(runnable).run();
}
@Test // GH-1131
void concludesForNonEmptyOptional() {
givenAScenario(it -> it.publish(new Object())
.andWaitForStateChange(delayed(Optional.of("value"))))
.expectSuccess();
}
@Test // GH-1131
void doesNotConcludeForEmptyOptional() {
givenAScenario(it -> it.publish(new Object())
.andWaitAtMost(Duration.ofMillis(500))
.andWaitForStateChange(delayed(Optional.empty())))
.expectFailure();
}
@Test // GH-1131
void concludesForNonEmptyCollection() {
givenAScenario(it -> it.publish(new Object())
.andWaitForStateChange(delayed(List.of("value"))))
.expectSuccess();
}
@Test // GH-1131
void doesNotConcludeForEmptyCollection() {
givenAScenario(it -> it.publish(new Object())
.andWaitAtMost(Duration.ofMillis(500))
.andWaitForStateChange(delayed(Collections.emptyList())))
.expectFailure();
}
@Test // GH-1131
void concludesForNonNull() {
givenAScenario(it -> it.publish(new Object())
.andWaitForStateChange(delayed(new Object())))
.expectSuccess();
}
@Test // GH-1131
void doesNotConcludeForNull() {
givenAScenario(it -> it.publish(new Object())
.andWaitAtMost(Duration.ofMillis(500))
.andWaitForStateChange(delayed(null)))
.expectFailure();
}
private Fixture givenAScenario(Consumer<Scenario> consumer) {
return new Fixture(consumer, DELAY, null, new DefaultAssertablePublishedEvents());
}