From b500d2113b405aafa95d5da57d2694f447ec390f Mon Sep 17 00:00:00 2001 From: "K. Siva Prasad Reddy" Date: Mon, 2 Sep 2024 20:06:15 +0530 Subject: [PATCH] Using @MockitoBean and @MockitoSpyBean --- etc/introducing-spring-modulith.adoc | 2 +- .../DatabaseSchemaInitializerIntegrationTests.java | 11 ++++++----- ...tPublicationAutoConfigurationIntegrationTests.java | 4 ++-- ...dbcEventPublicationRepositoryIntegrationTests.java | 4 ++-- ...tPublicationAutoConfigurationIntegrationTests.java | 4 ++-- ...EventPublicationConfigurationIntegrationTests.java | 4 ++-- .../neo4j/Neo4jEventPublicationRepositoryTest.java | 4 ++-- .../events/neo4j/Neo4jIndexInitializerTest.java | 4 ++-- .../fieldinjected/FieldInjectedIntegrationTest.java | 4 ++-- .../java/com/acme/myproject/moduleB/ModuleBTest.java | 4 ++-- .../java/com/acme/myproject/moduleC/ModuleCTest.java | 4 ++-- src/docs/antora/modules/ROOT/pages/events.adoc | 4 ++-- src/docs/antora/modules/ROOT/pages/testing.adoc | 6 +++--- 13 files changed, 30 insertions(+), 29 deletions(-) diff --git a/etc/introducing-spring-modulith.adoc b/etc/introducing-spring-modulith.adoc index d5d3a99d4..b3c333160 100644 --- a/etc/introducing-spring-modulith.adoc +++ b/etc/introducing-spring-modulith.adoc @@ -122,7 +122,7 @@ It can be link:{docs}#testing.bootstrap-modes[tweaked] to explicitly include oth == Using Events for Inter-module Interaction Shifting the integration testing focus towards application modules usually reveals their outgoing dependencies, typically established by references to Spring beans residing in other modules. -While those can be mocked (by using `@MockBean`) to satisfy the test execution, it is often a better idea to replace the cross-module bean dependencies with an application event being published and consuming that with the previously explicitly invoked component. +While those can be mocked (by using `@MockitoBean`) to satisfy the test execution, it is often a better idea to replace the cross-module bean dependencies with an application event being published and consuming that with the previously explicitly invoked component. Our example is already arranged in this preferred way, as it publishes an `OrderCompleted` event during the call to `OrderManagement.complete(…)`. Spring Modulith's `PublishedEvents` abstraction allows testing that an integration test case has caused particular application events to be published: diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerIntegrationTests.java index f0c98f4a2..c5fae8744 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerIntegrationTests.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/DatabaseSchemaInitializerIntegrationTests.java @@ -26,13 +26,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.modulith.events.core.EventSerializer; import org.springframework.modulith.testapp.TestApplication; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; import org.testcontainers.junit.jupiter.Testcontainers; /** @@ -48,7 +48,7 @@ class DatabaseSchemaInitializerIntegrationTests { @ContextConfiguration(classes = TestApplication.class) @Testcontainers(disabledWithoutDocker = true) static class TestBase { - @MockBean EventSerializer serializer; + @MockitoBean EventSerializer serializer; } @Nested @@ -73,7 +73,8 @@ void shouldCreateDatabaseSchemaOnStartUp() { @JdbcTest(properties = "spring.modulith.events.jdbc.schema-initialization.enabled=false") class InitializationDisabledExplicitly extends TestBase { - @SpyBean JdbcOperations operations; + @MockitoSpyBean + JdbcOperations operations; @Autowired Optional initializer; @Test // GH-3 @@ -91,7 +92,7 @@ void shouldNotCreateDatabaseSchemaOnStartUp() { @JdbcTest class InitializationDisabledByDefault extends TestBase { - @SpyBean JdbcOperations operations; + @MockitoSpyBean JdbcOperations operations; @Autowired Optional initializer; @Test // GH-3 diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfigurationIntegrationTests.java index 5447801e8..973a70681 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfigurationIntegrationTests.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationAutoConfigurationIntegrationTests.java @@ -20,11 +20,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.ApplicationContext; import org.springframework.modulith.events.core.EventPublicationRegistry; import org.springframework.modulith.events.core.EventSerializer; import org.springframework.modulith.testapp.TestApplication; +import org.springframework.test.context.bean.override.mockito.MockitoBean; /** * @author Dmitry Belyaev @@ -38,7 +38,7 @@ class JdbcEventPublicationAutoConfigurationIntegrationTests { @Autowired ApplicationContext context; - @MockBean EventSerializer serializer; + @MockitoBean EventSerializer serializer; @Test // GH-3 void bootstrapsApplicationComponents() { diff --git a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationRepositoryIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationRepositoryIntegrationTests.java index 55713082a..4c6edcb2b 100644 --- a/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationRepositoryIntegrationTests.java +++ b/spring-modulith-events/spring-modulith-events-jdbc/src/test/java/org/springframework/modulith/events/jdbc/JdbcEventPublicationRepositoryIntegrationTests.java @@ -36,7 +36,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Import; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.modulith.events.core.EventSerializer; @@ -69,7 +69,7 @@ static abstract class TestBase { @Autowired JdbcEventPublicationRepository repository; @Autowired JdbcRepositorySettings properties; - @MockBean EventSerializer serializer; + @MockitoBean EventSerializer serializer; @BeforeEach void cleanUp() { diff --git a/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfigurationIntegrationTests.java index 4d60ae017..ae9ae88b9 100644 --- a/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfigurationIntegrationTests.java +++ b/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfigurationIntegrationTests.java @@ -24,7 +24,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.modulith.events.core.EventSerializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestConstructor; @@ -41,7 +41,7 @@ class JpaEventPublicationAutoConfigurationIntegrationTests { private final BeanFactory factory; - @MockBean EventSerializer serializer; + @MockitoBean EventSerializer serializer; @Test // GH-10 void registersJpaEventPublicationPackageForAutoConfiguration() { diff --git a/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationConfigurationIntegrationTests.java index 19ce64151..a39265c22 100644 --- a/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationConfigurationIntegrationTests.java +++ b/spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationConfigurationIntegrationTests.java @@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.ApplicationContext; import org.springframework.modulith.events.core.EventPublicationRegistry; import org.springframework.modulith.events.core.EventSerializer; @@ -41,7 +41,7 @@ class JpaEventPublicationConfigurationIntegrationTests { private final ApplicationContext context; - @MockBean EventSerializer serializer; + @MockitoBean EventSerializer serializer; @Test void bootstrapsApplicationComponents() { diff --git a/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jEventPublicationRepositoryTest.java b/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jEventPublicationRepositoryTest.java index e78bef27e..293839a11 100644 --- a/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jEventPublicationRepositoryTest.java +++ b/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jEventPublicationRepositoryTest.java @@ -34,7 +34,7 @@ import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -69,7 +69,7 @@ class Neo4jEventPublicationRepositoryTest { @Autowired Driver driver; @Autowired Environment environment; - @MockBean EventSerializer eventSerializer; + @MockitoBean EventSerializer eventSerializer; CompletionMode completionMode; diff --git a/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jIndexInitializerTest.java b/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jIndexInitializerTest.java index 6ef2d6a89..fc6c460f1 100644 --- a/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jIndexInitializerTest.java +++ b/spring-modulith-events/spring-modulith-events-neo4j/src/test/java/org/springframework/modulith/events/neo4j/Neo4jIndexInitializerTest.java @@ -27,7 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.autoconfigure.data.neo4j.DataNeo4jTest; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.neo4j.core.Neo4jClient; @@ -52,7 +52,7 @@ static class TestBase { @Container private static Neo4jContainer neo4jContainer = new Neo4jContainer<>(DockerImageName.parse("neo4j:5")) .withRandomPassword(); - @MockBean EventSerializer eventSerializer; + @MockitoBean EventSerializer eventSerializer; @Configuration static class Config { diff --git a/spring-modulith-integration-test/src/test/java/com/acme/myproject/fieldinjected/FieldInjectedIntegrationTest.java b/spring-modulith-integration-test/src/test/java/com/acme/myproject/fieldinjected/FieldInjectedIntegrationTest.java index a19db4b79..7dc8e74d2 100644 --- a/spring-modulith-integration-test/src/test/java/com/acme/myproject/fieldinjected/FieldInjectedIntegrationTest.java +++ b/spring-modulith-integration-test/src/test/java/com/acme/myproject/fieldinjected/FieldInjectedIntegrationTest.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.modulith.core.ApplicationModules; import org.springframework.modulith.test.ModuleTestExecution; @@ -36,7 +36,7 @@ class FieldInjectedIntegrationTest { @Autowired ModuleTestExecution execution; - @MockBean ServiceComponentA dependency; + @MockitoBean ServiceComponentA dependency; @Test void rejectsFieldInjection() { diff --git a/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleB/ModuleBTest.java b/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleB/ModuleBTest.java index 9e2bf3cbc..a2161df55 100644 --- a/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleB/ModuleBTest.java +++ b/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleB/ModuleBTest.java @@ -22,7 +22,7 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurationPackages; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.context.ApplicationContext; import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode; import org.springframework.modulith.test.TestUtils; @@ -55,7 +55,7 @@ void failsToStartBecauseServiceComponentAIsMissing() throws Exception { static class WithMocksTest { @Autowired ApplicationContext context; - @MockBean ServiceComponentA serviceComponentA; + @MockitoBean ServiceComponentA serviceComponentA; @Test void bootstrapsModuleB() { diff --git a/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleC/ModuleCTest.java b/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleC/ModuleCTest.java index c821924cc..5a11afe9b 100644 --- a/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleC/ModuleCTest.java +++ b/spring-modulith-integration-test/src/test/java/com/acme/myproject/moduleC/ModuleCTest.java @@ -20,7 +20,7 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.bean.override.mockito.MockitoBean; import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode; import org.springframework.modulith.test.TestUtils; @@ -61,7 +61,7 @@ void failsWithDirectDependency() { @NonVerifyingModuleTest(BootstrapMode.DIRECT_DEPENDENCIES) static class SucceedsWithDirectDependencyPlusItsDependenciesMocksTest { - @MockBean ServiceComponentA serviceComponentA; + @MockitoBean ServiceComponentA serviceComponentA; @Test void bootstrapsContext() { diff --git a/src/docs/antora/modules/ROOT/pages/events.adoc b/src/docs/antora/modules/ROOT/pages/events.adoc index bf38d6f7e..8c7544f8a 100644 --- a/src/docs/antora/modules/ROOT/pages/events.adoc +++ b/src/docs/antora/modules/ROOT/pages/events.adoc @@ -228,7 +228,7 @@ Using the transactional event publication log requires a combination of artifact |MongoDB |`spring-modulith-starter-mongodb` -|Using JDBC as persistence technology. Also enables MongoDB transactions and requires a replica set setup of the server to interact with. The transaction auto-configuration can be disabled by setting the `spring.modulith.events.mongobd.transaction-management.enabled` property to `false`. +|Using MongoDB as persistence technology. Also enables MongoDB transactions and requires a replica set setup of the server to interact with. The transaction auto-configuration can be disabled by setting the `spring.modulith.events.mongobd.transaction-management.enabled` property to `false`. |Neo4j |`spring-modulith-starter-neo4j` @@ -270,7 +270,7 @@ dependencies { This artifact contains two primary abstractions that are available to application code as Spring Beans: -* `CompletedEventPublications` -- This interface allows accessing all completed event publications, and provides an API to immediately purge all of them from the database or the completed publications older that a given duration (for example, 1 minute). +* `CompletedEventPublications` -- This interface allows accessing all completed event publications, and provides an API to immediately purge all of them from the database or the completed publications older than a given duration (for example, 1 minute). * `IncompleteEventPublications` -- This interface allows accessing all incomplete event publications to resubmit either the ones matching a given predicate or older than a given `Duration` relative to the original publishing date. [[publication-registry.completion]] diff --git a/src/docs/antora/modules/ROOT/pages/testing.adoc b/src/docs/antora/modules/ROOT/pages/testing.adoc index 010abc55a..62ff2ed91 100644 --- a/src/docs/antora/modules/ROOT/pages/testing.adoc +++ b/src/docs/antora/modules/ROOT/pages/testing.adoc @@ -90,7 +90,7 @@ Java:: @ApplicationModuleTest class InventoryIntegrationTests { - @MockBean SomeOtherComponent someOtherComponent; + @MockitoBean SomeOtherComponent someOtherComponent; } ---- Kotlin:: @@ -100,11 +100,11 @@ Kotlin:: @ApplicationModuleTest class InventoryIntegrationTests { - @MockBean SomeOtherComponent someOtherComponent + @MockitoBean SomeOtherComponent someOtherComponent } ---- ====== -Spring Boot will create bean definitions and instances for the types defined as `@MockBean` and add them to the `ApplicationContext` bootstrapped for the test run. +Spring Boot will create bean definitions and instances for the types defined as `@MockitoBean` and add them to the `ApplicationContext` bootstrapped for the test run. If you find your application module depending on too many beans of other ones, that is usually a sign of high coupling between them. The dependencies should be reviewed for whether they are candidates for replacement by publishing xref:events.adoc#events[domain events].