Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Spring Boot's @MockBean and @SpyBean with Framework's @MockitoBean and @MockitoSpyBean #795

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion etc/introducing-spring-modulith.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -48,7 +48,7 @@ class DatabaseSchemaInitializerIntegrationTests {
@ContextConfiguration(classes = TestApplication.class)
@Testcontainers(disabledWithoutDocker = true)
static class TestBase {
@MockBean EventSerializer serializer;
@MockitoBean EventSerializer serializer;
}

@Nested
Expand All @@ -73,7 +73,7 @@ void shouldCreateDatabaseSchemaOnStartUp() {
@JdbcTest(properties = "spring.modulith.events.jdbc.schema-initialization.enabled=false")
class InitializationDisabledExplicitly extends TestBase {

@SpyBean JdbcOperations operations;
@MockitoSpyBean JdbcOperations operations;
@Autowired Optional<DatabaseSchemaInitializer> initializer;

@Test // GH-3
Expand All @@ -91,7 +91,7 @@ void shouldNotCreateDatabaseSchemaOnStartUp() {
@JdbcTest
class InitializationDisabledByDefault extends TestBase {

@SpyBean JdbcOperations operations;
@MockitoSpyBean JdbcOperations operations;
@Autowired Optional<DatabaseSchemaInitializer> initializer;

@Test // GH-3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -38,7 +38,7 @@ class JdbcEventPublicationAutoConfigurationIntegrationTests {

@Autowired ApplicationContext context;

@MockBean EventSerializer serializer;
@MockitoBean EventSerializer serializer;

@Test // GH-3
void bootstrapsApplicationComponents() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -69,7 +69,7 @@ static abstract class TestBase {
@Autowired JdbcEventPublicationRepository repository;
@Autowired JdbcRepositorySettings properties;

@MockBean EventSerializer serializer;
@MockitoBean EventSerializer serializer;

@BeforeEach
void cleanUp() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -41,7 +41,7 @@ class JpaEventPublicationAutoConfigurationIntegrationTests {

private final BeanFactory factory;

@MockBean EventSerializer serializer;
@MockitoBean EventSerializer serializer;

@Test // GH-10
void registersJpaEventPublicationPackageForAutoConfiguration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -41,7 +41,7 @@ class JpaEventPublicationConfigurationIntegrationTests {

private final ApplicationContext context;

@MockBean EventSerializer serializer;
@MockitoBean EventSerializer serializer;

@Test
void bootstrapsApplicationComponents() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -69,7 +69,7 @@ class Neo4jEventPublicationRepositoryTest {
@Autowired Driver driver;
@Autowired Environment environment;

@MockBean EventSerializer eventSerializer;
@MockitoBean EventSerializer eventSerializer;

CompletionMode completionMode;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -36,7 +36,7 @@ class FieldInjectedIntegrationTest {

@Autowired ModuleTestExecution execution;

@MockBean ServiceComponentA dependency;
@MockitoBean ServiceComponentA dependency;

@Test
void rejectsFieldInjection() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -55,7 +55,7 @@ void failsToStartBecauseServiceComponentAIsMissing() throws Exception {
static class WithMocksTest {

@Autowired ApplicationContext context;
@MockBean ServiceComponentA serviceComponentA;
@MockitoBean ServiceComponentA serviceComponentA;

@Test
void bootstrapsModuleB() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -61,7 +61,7 @@ void failsWithDirectDependency() {
@NonVerifyingModuleTest(BootstrapMode.DIRECT_DEPENDENCIES)
static class SucceedsWithDirectDependencyPlusItsDependenciesMocksTest {

@MockBean ServiceComponentA serviceComponentA;
@MockitoBean ServiceComponentA serviceComponentA;

@Test
void bootstrapsContext() {
Expand Down
4 changes: 2 additions & 2 deletions src/docs/antora/modules/ROOT/pages/events.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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]]
Expand Down
6 changes: 3 additions & 3 deletions src/docs/antora/modules/ROOT/pages/testing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Java::
@ApplicationModuleTest
class InventoryIntegrationTests {

@MockBean SomeOtherComponent someOtherComponent;
@MockitoBean SomeOtherComponent someOtherComponent;
}
----
Kotlin::
Expand All @@ -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].
Expand Down