Example multi module spring boot project using gradle.
There are two types of gradle projects in this repo: components and applications. Components contain
reusable code useful across a range of applications. Component projects produce a .jar that can
be used a dependency by other components or applications in this repo. all component projects
must be located in the components/
directory.
All projects in this repo us the same version of Java, Spring Boot and other libraries. There is only one version of all dependencies across all component and applications in this repo. When you upgrade a dependency you upgrade it for everything in this repo. This policy makes it easy to stay up to date with the latest versions of third party dependencies.
Gradle with the Kotlin DSL is used for building the application. Build logic has been
extracted into buildSrc
as recommended by Gradle best practices. A gradle java-platfrom
is used to align dependencies across all projects in this repo. Spring Boot BOM is used to manage
the classpath, but not the spring gradle plugin.
The Spring boot version is set by editing the spring-boot-gradle-plugin
version in
buildSrc/build.gradle.kts
. The Java Platform defined by this project use the spring
boot version defined in the gradle plugin
api(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
this approach makes sure that there is only one place to change the spring version and both
the plugin and dependency management will use the same version.
Code should be formatted using the Google java style guide. The Gradle spotless plugin ensures
to make sure that the code formatting follows the standards. Spotless is configured to auto format
.sql
file using dbBeaver. Code formatting violations cause the build to fail, but you can
easily fix style issues automatically using ./gradlew spotlessApply build
.
This project uses the gradle test fixtures plugin to enable each component to ship classes designed to make testing writing easier.
If a project uses spring it must include the spring-conventions
as a dependency. This project
contains a very small number of base classes and components that should always be on the classpath.
There are three types of tests with framework support.
- Unit
- Component
- Integration
Unit tests focus on testing a class in isolation with no external dependencies. This means no database, web container, or spring application context. The code being tested executes on the same thread running junit5 test methods. Unit tests make muse of the following frameworks.
Component tests focus on testing a group of related classes within a spring application context,
with access to a PostgreSQL database, and MockMVC environment. A Tomcat server is not started,
therefore the code being tested executes on the same thread running junit5 test methods.
@Transactional
tests can rollback at the end of the test method to restore database state to
it's original condition. In addition to the unit testing frameworks component test make use of.
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
is used for executing tests. MockMvc Spring
framework has some limitations any code that depends directly on servlet container will not work
for example error dispatching to send a request to the error page will not work. @ControllerAdvice
needs to be explicitly configured into the MockMVC environment, so does spring security filter
chain.
Loading data into the database can be done via @Sql(scripts = path to .sql on classpath)
from
org.springframework.test.context.jdbc.Sql
this will execute a data loading script as part of
a test method or test class and rollback the transaction at the end of the test method.
Integration tests focus on testing the backend by sending it requests over the network. Therefore,
a running Tomcat server and PostgreSQL server are required to run the integration tests. Test
methods in Junit are sending requests to tomcat and therefore the code under test is executing
on the tomcat thread pool, therefore @Transactional
tests will commit and it is not possible
to rollback a transactional test and restore the database to a well known state. In addition to
the frameworks used by Unit and Component Tests, the following frameworks are also used.
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
is used launch a fully functional
spring boot application on a random port for testing.