My project has a DataSource class that implements the database connection parameters, as well as the initialization of the database connection:
public class DataSource {
private static HikariConfig config = new HikariConfig();
private static HikariDataSource ds;
public static HikariDataSource getDataSource() {
if (ds == null) {
config.setJdbcUrl(System.getProperty("jdbcUrl","jdbc:postgresql://localhost:5433/postgres"));
config.setUsername(System.getProperty("jdbcUser","postgres"));
config.setPassword(System.getProperty("jdbcPassword","postgres"));
ds = new HikariDataSource(config);
initDatabase();
}
return ds;
}
private static void initDatabase() {
try {
DatabaseConnection connection = new JdbcConnection(ds.getConnection());
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
Liquibase liquibase = new Liquibase(
System.getProperty("liquibaseFile","liquibase.xml"),
new ClassLoaderResourceAccessor(),
database);
liquibase.update(new Contexts());
} catch (SQLException | LiquibaseException e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
The JUnit library is used to develop unit tests for project dao methods. A base class has been created with the help of which the parameters for connecting to the database are redefined (in this case, to H2):
public class Base {
@BeforeAll
static void setup() {
System.setProperty("jdbcUrl", "jdbc:h2:mem:test_" + UUID.randomUUID());
System.setProperty("jdbcUser", "sa");
System.setProperty("jdbcPassword", "");
System.setProperty("liquibaseFile", "liquibase_test.xml");
}
@BeforeEach
void init() {
setup();
}
}
How can I make sure that System.setProperty properties are redefined within a single method? It is important that the behavior of the method is similar to that of @BeforeEach instead of the @BeforeAll annotation. I tried to put @BeforeEach instead of @BeforeAll, removing static, but when the test is executed, the postgress database is accessed, and not H2, as required by the condition.
Instead of using system properties to configure the database make your classore easily configurable and testable. You could implement a singleton pattern and an initializing method for example.
Having said that, using a different database for production than for testing may not reproduce the exact behavior.