Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent import.sql being executed in Spring Boot unit test

I have an import.sql file with a few INSERT statements in my classpath. When running my application with profile=devel it's data is being loaded into a postgres db, which is OK so far.

When executing tests with the test profile import.sql is also being triggered for import which leads to "table not found" exceptions. Not sure what the reason is here, but I don't want to use that data for tests anyway.

How can I stop this? Setting hibernate.ddl-auto=none for the test profile does not seem to be a solution as it prevents generation of the schema as well.

like image 633
Pacman Avatar asked Dec 16 '16 16:12

Pacman


People also ask

What is SQL init mode always?

sql. init mode to always initialize the SQL database. It also enables the fail-fast feature by default for the script-based database initializer, i.e. the application cannot start if the scripts throw exceptions.

What is DDL Auto in spring boot?

ddl-auto explicitly and the standard Hibernate property values are none , validate , update , create , and create-drop . Spring Boot chooses a default value for you based on whether it thinks your database is embedded. It defaults to create-drop if no schema manager has been detected or none in all other cases.

What is spring SQL init mode?

sql is executed to populate the database. Also, script-based initialization is performed by default only for embedded databases, to always initialize a database using scripts, we'll have to use: spring.sql.init.mode=always. Please refer to official Spring documentation on initializing databases using SQL scripts.


1 Answers

As far as I know, you can't configure it. The import.sql file is automatically invoked by Hibernate as soon as you use create-drop or create mode. This is also mentioned by the documentation and has nothing to do with Spring:

In addition, a file named import.sql in the root of the classpath is executed on startup if Hibernate creates the schema from scratch (that is, if the ddl-auto property is set to create or create-drop).

My guess is that you still want to keep generating your tables in your test scenarios. In that case, you probably want to switch to Spring boot's datasource initialization, by adding a file called schema.sql and data.sql on the classpath.

This file will be picked automatically on startup by Spring boot (only for embedded datasources in Spring boot 2.0), which is also mentioned by the documentation:

Spring Boot can automatically create the schema (DDL scripts) of your DataSource and initialize it (DML scripts). It loads SQL from the standard root classpath locations: schema.sql and data.sql, respectively.

Now, to be able to disable loading data during your test phase, you can work with profiles. For example, with Spring boot 2.x you can disable this by using the following property:

spring.datasource.initialization-mode=never # Property for Spring boot 2.0
spring.datasource.initialize=false # Property for Spring boot 1.0

Be aware, this disables both the schema creation, and the data loading SQL files. Disabling only the data.sql file is not possible, but can be achieved by using a simple trick by renaming the default filename that Spring boot will look for:

spring.datasource.data=somethingelse.sql

If you only configure this property during your tests, Spring boot will look for a file called somethingelse.sql, and won't pick up your data.sql file. While when running with the dev profile, you discard this property, and Spring boot will look for (and find) data.sql.


An alternative approach that works for both Spring boot's schema.sql/data.sql and Hibernate's import.sql is to work with Maven profiles and to load different classpath folders when running tests. However, I wouldn't recommend doing so, because it makes running tests in IDEs a bit more difficult.

like image 72
g00glen00b Avatar answered Oct 28 '22 02:10

g00glen00b