You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+56-84Lines changed: 56 additions & 84 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,15 +1,23 @@
1
1
# Spring Local PostgreSQL
2
2
3
3
## Description
4
-
Provides configuration of an embedded PostgreSQL database (via Testcontainers)
5
-
within Spring Boot Applications for local development and testing.
4
+
Provides enhanced configuration of an embedded PostgreSQL database provided by Testcontainers. For use within Spring Boot Applications to support local development in addition to integration test execution.
6
5
7
-
Requires minimal configuration using Spring conventions, but a variety of optional properties are supported to override default behavior.
6
+
Requires minimal configuration using Spring conventions, but a variety of optional properties are provided to override default behavior and control the underlying container's configuration by profile.
7
+
8
+
## Features
9
+
- Configure whether the embedded PostgreSQL is active or not. Allows you to control its activation by profile.
10
+
- Configure the Docker image to contain the embedded PostgreSQL. Allows you to match your local and test environments with the version of PostgreSQL running in production.
11
+
- Configure the embedded PostgreSQL to run on a defined, fixed port. Useful for local development so that developers can connect to the database with their client of choice with consistent configuration.
12
+
- Configure whether to follow the containers log output. Useful for troubleshooting.
13
+
- Configure the database name to match production.
14
+
- Configure a database super user to handle migration scripts and a second user with fewer privileges for the Application to use.
15
+
- Configure an SQL script to run when the PostgreSQL database is spun up.
8
16
9
17
## Rationale
10
18
When developing an Application that uses PostgreSQL in production, an embedded PostgreSQL server provides the benefits of using an in-memory database, like H2, but avoids the downsides. The database is spun up and torn down when the Application starts up and shuts down, but developers are able to utilize PostgreSQL features (that alternatives like H2 may not support) and the test and local environments better resemble production. Development is more effective and reliable.
11
19
12
-
While Testcontainers is meant to be used exclusively in support of integration tests, this module is designed to support running the Application locally as well, reducing the overhead of maintaining Testcontainers and some other solution that fundamentally does the same thing. There is no need to maintain a local PostgreSQL server nor additional Docker configuration inside or outside the project.
20
+
While Testcontainers is meant to be used exclusively in support of integration tests, this project is designed to support running the Application locally as well, reducing the overhead of maintaining Testcontainers and some other solution that fundamentally does the same thing. There is no need to maintain a local PostgreSQL server nor additional Docker configuration inside or outside the project.
While it is possible to configure this project as a compile dependency, and control its activation with profiles, it is not good practice. This project should always be configured as a test dependency.
57
+
58
+
However, this means that all configuration of this project can only reside in your project's test source, which is fine for integration tests, but= what about running the Application locally?
59
+
60
+
To do this we implement an approach surfaced in this [article](https://bsideup.github.io/posts/local_development_with_testcontainers/) by Sergei Egorov.
73
61
74
-
First, add this module as a dependency in your project:
62
+
First, Add this project's artifact to your project as a test dependency:
75
63
```xml
76
64
<dependency>
77
65
<groupId>io.github.quinnandrews</groupId>
78
66
<artifactId>spring-local-postgresql</artifactId>
79
67
<version>1.0-SNAPSHOT</version>
68
+
<scope>test</scope>
80
69
</dependency>
81
70
```
71
+
(NOTE: This project's artifact is NOT yet available in Maven Central)
82
72
83
-
Next, add `@EnableLocalPostreSQL` to your Spring Boot Application Class:
84
-
```java
85
-
@EnableLocalPostgreSQL
86
-
@SpringBootApplication
87
-
publicclassApplication {
88
-
89
-
publicstaticvoidmain(finalString[] args) {
90
-
SpringApplication.run(Application.class, args);
91
-
}
92
-
}
93
-
```
94
-
95
-
Then define the following property for the profiles that should initialize the embedded PostgreSQL:
96
-
```properties
97
-
spring.local.postgresql.engaged=true
98
-
```
99
-
100
-
If desired, define any of the following properties to override default behavior (see below for detailed descriptions):
73
+
Next, create properties files in your the test resources directory for `local` and `test` profiles with your configuration of choice. We recommend that the `local` profile is configured with a fixed port while the `test` profile is configured to use a random port, which is considered best practice for integration tests. And you may want do things like enable following of the container logs for the `local` profile as well:
Understandably, one may prefer this module as a test dependency rather than a compile dependency. But this means that all configuration for this module can only reside in your project's test source, which is fine for integration tests, but how, then, can you run the Application locally?
116
-
117
-
To do this we implement an approach surfaced in this [article](https://bsideup.github.io/posts/local_development_with_testcontainers/) by Sergei Egorov.
118
-
119
-
First, add this module as a test dependency in your project:
Next, add a Spring Boot Application Class to your project's test source that includes the `@EnableLocalPostgreSQL` Annotation and passes the Application Class in your project's main source to the `run` method (so that Configuration in the main source is initialized):
98
+
99
+
Then add a Spring Boot Application Class to your project's test source that includes the `@EnableLocalPostgreSQL` Annotation and passes the Application Class in your project's main source to the `run` method (so that Configuration in the main source is initialized):
129
100
```java
130
101
@EnableLocalPostgreSQL
131
102
@SpringBootApplication
@@ -137,7 +108,7 @@ public class LocalDevApplication {
137
108
}
138
109
```
139
110
140
-
Then you can reference `LocalApplication.class` in your integration tests to enable the embedded PostgreSQL by using the `classes` attribute on `@SpringBootTest`:
111
+
Now you can reference `LocalApplication.class` in your integration tests to enable the embedded PostgreSQL by using the `classes` attribute on `@SpringBootTest`:
141
112
```java
142
113
@ActiveProfiles("test")
143
114
@SpringBootTest(classes=LocalApplication.class)
@@ -146,7 +117,7 @@ class IntegrationTest {
146
117
}
147
118
```
148
119
149
-
Or, alternatively, your integration tests can ignore `LocalApplication.class` and enable the embedded PostgreSQL by using `@EnableLocalPostgreSQL`:
120
+
Or, alternatively, your integration tests can include the embedded PostgreSQL directly by using `@EnableLocalPostgreSQL` (NOTE: You may need to declare the Application Class in your main source using `classes` attribute to avoid conflicts):
150
121
```java
151
122
@EnableLocalPostgreSQL
152
123
@ActiveProfiles("test")
@@ -155,13 +126,14 @@ class IntegrationTest {
155
126
156
127
}
157
128
```
129
+
158
130
Then you can create a `Run Configuration` in IntelliJ IDEA, for example, setting `LocalApplication.class` as the `Main Class` and defining `local` as the active profile.
159
131
160
-
Now when you run the `Run Configuration` or your integration tests, the embedded PostgreSQL will be initialized, assuming that the `local` and `test` profiles have set the `spring.local.postgresql.engaged` property to `true'.`
132
+
Now when you run the `Run Configuration` or your integration tests, the embedded PostgreSQL will be initialized.
161
133
162
-
**But there is a way to make this even more convenient.**
134
+
**_But there is a way to make this even more convenient._**
163
135
164
-
If your integration tests reference `LocalApplication.class`, it's worth noting that the `main` method isn't actually executed in that case. Spring is doing something different.
136
+
If your integration tests reference `LocalApplication.class`, it's worth noting that the `main` method isn't actually executed when the tests run. Spring is using the Class for reference and doing something different in place of executing the `main` method.
165
137
166
138
What this means is that you can activate the `local` profile explicitly in the body of the `main` method:
167
139
```java
@@ -177,7 +149,7 @@ public class LocalApplication {
177
149
}
178
150
```
179
151
180
-
Now you can run the Application locally in IntelliJ IDEA by simply right-clicking on `LocalApplication.class` in the Project Panel and selecting `Run 'LocalApplication'` from the Context Menu, which will also create a `Run Configuration` for later use.
152
+
Now you can run the Application locally in IntelliJ IDEA by simply right-clicking on `LocalApplication.class` in the Project Panel and selecting `Run 'LocalApplication'` from the Context Menu, which will also create a `Run Configuration` for later use, but you don't need to do make any changes to the `Run Configuration`. Its default setting work just fine.
0 commit comments