I have a standard spring boot application with this docker file:
FROM maven:latest AS maven
WORKDIR /usr/src/app
COPY . /usr/src/app
# Compile and package the application to an executable JAR
RUN mvn package
FROM amazoncorretto:17-alpine-jdk
ARG JAR_FILE=app.jar
WORKDIR /opt/app
# Copy the jar from the maven stage to the /opt/app directory of the current stage.
COPY --from=maven /usr/src/app/target/${JAR_FILE} /opt/app/
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
My application.properties
file has the connection spring to my postgres db running in a docker container:
# datasource
spring.datasource.url=jdbc:postgresql://db:5432/myApp?currentSchema=gpclinic&createDatabaseIfNotExist=true
spring.datasource.username=uname
spring.datasource.password=pword
When I run:
docker build -t myApp .
I get a failure as the unit tests fail because the DB container is not running.
Will I need a Postgres container running to pass my tests? Or what is the best way to get around this?
4
Answers
As I understand you need insert endpoint of postgres where
db
injdbc:postgresql://db:5432
Or if you have docker-compose.yml, service name of postgresql should be
db
Skip tests while building the image, see Maven package/install without test (skip tests)
Once the image is built, you can run the tests by starting a container in an environment where a DB endpoint is available.
Roughly speaking, when you build your image under the hood docker creates a series of intermediate containers, one for every line in your Dockerfile.
You are trying to connect from one of this intermediate containers, the one which is packaging your application, to another container running Postgres in your host.
I am not sure if it will work – the subject had been broadly covered here in SO – but, if you are using MacOS or Windows, and your Postgres container exposes the port to the host, you could try modifying the connection string in your Spring properties and use the network address
host.docker.internal
to try reaching the database:You mentioned compose as well, but again I am not sure whether it is possible. Please, see this related SO question.
Having said that, please, be aware that the solution has different drawbacks, among others:
I think that, as suggested in other answers, it is preferable to skip the unit tests execution while building your image. You can achieve this in several ways, for example (
clean
is not necessary, but I usually clean before packaging the application):Or:
The same approach is addressed in this SO related question, for instance.
Following this approach, if you really need to run your tests, it is preferable to use a devoted step in a CI/CD system pipeline, for example, instead of running it in the docker build.
Finally, please, consider why you are accessing a database in a unit test: in my opinion, and please, forgive me, because SO answer shouldn’t be opinion based, it is something that you can find in an integration test, for example, but I think it is not commonly used in unit tests.
Even in the case that using a database is a must, for simplicity, predictability, in order to improve portability and build isolation, please, consider use an in-memory one like H2 with the necessary information, and run your tests against it instead.
I think the Below Answer might Help you
May be You can Add h2 database properites in a seperate properties file
application-test.properties.
And may be Change the Scope in original application.properties
And you can Third Dependency for h2 Database as it will not be dependent on any other Database ..h2 Database runs in your JVM
So in this Case you Dont need any container to Run the Tests…Once the Tests Passes your package will be built.