All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kiwiproject.test.junit.jupiter.H2FileBasedDatabaseExtension Maven / Gradle / Ivy

There is a newer version: 3.7.0
Show newest version
package org.kiwiproject.test.junit.jupiter;

import lombok.Getter;
import lombok.experimental.Delegate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.kiwiproject.test.h2.H2DatabaseTestHelper;
import org.kiwiproject.test.h2.H2FileBasedDatabase;

/**
 * JUnit Jupiter extension that creates a file-based H2 database before all tests and deletes it after all tests
 * have executed. It also provides for injection of the database into test lifecycle methods that declare
 * a {@link H2FileBasedDatabase} annotated with {@link H2Database}.
 * 

* You can register the extension via {@code ExtendWith} and then use parameter resolution with the {@link H2Database} * annotation to obtain the {@link H2FileBasedDatabase} instance in a lifecycle or test method. Example: *

 * {@literal @}ExtendWith(H2FileBasedDatabaseExtension.class)
 *  class MyFirstTest {
 *
 *     {@literal @}BeforeEach
 *      void setUp(@H2Database H2FileBasedDatabase database) { ... }
 *
 *     {@literal @}Test
 *      void shouldDoSomethingWithTheDatabase(@H2Database H2FileBasedDatabase database) { ... }
 *  }
 * 
*

* Alternatively, if you need to supply another extension with the H2 database, then you can register the extension * on a static field using {@code @RegisterExtension}. Here is an example using a theoretical extension named * {@code DaoExtension} that requires a {@code DataSource}. The data source is obtained from the * {@link H2FileBasedDatabase} provided by this extension: *

 * class MySecondTest {
 *
 *    {@literal @}RegisterExtension
 *     static final H2FileBasedDatabaseExtension DATABASE_EXTENSION = new H2FileBasedDatabaseExtension();
 *
 *    {@literal @}RegisterExtension
 *     final DaoExtension<PersonDao> jdbi3DaoExtension =
 *             DaoExtension.<PersonDao>builder()
 *                     .daoType(PersonDao.class)
 *                     .dataSource(DATABASE_EXTENSION.getDataSource())  // supply the DataSource here
 *                     .plugin(new H2DatabasePlugin())
 *                     .build();
 * }
 * 
* NOTE:The second example only works when the extension that requires the {@link H2FileBasedDatabase} * is an instance field. If it is static, it will not work! *

* When using this extension via {@code @RegisterExtension}, you can use the getter methods to retrieve the entire * {@link H2FileBasedDatabase} object or its individual properties. When using it with {@code @ExtendWith} and an * injected parameter, you obviously have direct access to the {@link H2FileBasedDatabase} object. */ @Slf4j public class H2FileBasedDatabaseExtension implements BeforeAllCallback, AfterAllCallback, ParameterResolver { private static final String DATABASE_KEY = "database"; @Getter @Delegate private H2FileBasedDatabase database; /** * Creates a new H2 file-based database. * * @param context extension context */ @Override public void beforeAll(ExtensionContext context) { database = H2DatabaseTestHelper.buildH2FileBasedDatabase(); LOG.trace("Created database: {}", database); var namespace = createNamespace(); context.getStore(namespace).put(DATABASE_KEY, database); } /** * Deletes the H2 file-based database. * * @param context extension context * @throws Exception if the database directory could not be deleted */ @Override public void afterAll(ExtensionContext context) throws Exception { LOG.trace("Deleting database: {}", database); FileUtils.deleteDirectory(database.getDirectory()); } /** * Does the parameter need to be resolved? * * @param parameterContext parameter context * @param extensionContext extension context * @return true if the {@code parameterContext} is annotated with {@link H2Database} */ @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { return parameterContext.isAnnotated(H2Database.class); } /** * Resolve the parameter annotated with {@link H2Database} into a {@link H2FileBasedDatabase}. * * @param parameterContext parameter context * @param extensionContext extension context * @return the resolved {@link H2FileBasedDatabase} */ @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { var namespace = createNamespace(); return getDatabase(extensionContext, namespace); } private ExtensionContext.Namespace createNamespace() { return ExtensionContext.Namespace.create(getClass(), "H2FileBasedDatabase", Thread.currentThread().getName()); } private H2FileBasedDatabase getDatabase(ExtensionContext context, ExtensionContext.Namespace namespace) { return context.getStore(namespace).get(DATABASE_KEY, H2FileBasedDatabase.class); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy