I’m working on a Java 21, Spring Boot 3.3 application using Vaadin 24 and EclipseStore 1.4.0 for embedded storage. I’m having trouble setting up a simple test to ensure that I can read and write to the database using EclipseStore.
In production, my setup works fine, but I’m struggling to get tests working. I want to test my repository class (EclipseProjectAdapter
) that interacts with EclipseStore’s EmbeddedStorageManager
. For my test, I want to use an in-memory storage or a temporary database to avoid interacting with my production database.
Here’s what I’ve tried so far:
Test class:
@SpringBootTest(classes = TestConfig.class)
@Tag("database")
class EclipseProjectAdapterTest {
@Autowired
EmbeddedStorageManager storageManager;
EclipseProjectAdapter adapter;
@BeforeEach
void setUp() {
storageManager.start();
storageManager.setRoot(new DataRoot());
adapter = new EclipseProjectAdapter(storageManager);
}
@AfterEach
void tearDown() {
storageManager.shutdown();
}
@Test
void canReadAndWrite() {
List<Project> projects = adapter.findAll();
assertThat(projects).isEmpty();
Project project = Project.create("Project A");
adapter.save(project);
List<Project> allProjects = adapter.findAll();
assertThat(allProjects).hasSize(1);
assertThat(allProjects.getFirst().name()).isEqualTo("Project A");
}
}
Test configuration:
@Configuration
public class TestConfig {
@Bean
@Primary
EmbeddedStorageManager inMemoryStorageManager(
@Autowired EclipseStoreProperties myConfiguration,
@Autowired EmbeddedStorageManagerFactory managerFactory,
@Autowired EmbeddedStorageFoundationFactory foundationFactory) {
String tempDir = System.getProperty("java.io.tmpdir") + "/test-store-" + UUID.randomUUID();
myConfiguration.setStorageDirectory(tempDir);
EmbeddedStorageFoundation<?> storageFoundation = foundationFactory.createStorageFoundation(myConfiguration);
return managerFactory.createStorage(storageFoundation, false);
}
}
test/resources/application.properties
org.eclipse.store.storage-directory=${java.io.tmpdir}/${random.int}
Error message:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.eclipse.store.integrations.spring.boot.types.configuration.EclipseStoreProperties'
available: expected at least 1 bean which qualifies as autowire candidate.
What I’ve Tried:
- Including the
eclipsestore-spring-boot-starter
dependency in mypom.xml
. - Explicitly defining the
EclipseStoreProperties
,EmbeddedStorageManagerFactory
, andEmbeddedStorageFoundationFactory
beans in myTestConfig
. - Verifying that the auto-configuration of EclipseStore is enabled.
- Checking that my test profile and properties are correctly set to use a temporary directory for storage.
Despite these efforts, I keep running into issues with missing beans like EmbeddedStorageManagerFactory
and EclipseStoreProperties
. I’m not sure how to properly configure a test environment for EclipseStore.
Questions:
- How can I configure my Spring Boot test to use an in-memory or temporary storage with EclipseStore?
- Is there a way to use TestContainers or a similar approach with EclipseStore for testing purposes?
- Are there any best practices or examples for testing with EclipseStore that could help resolve these issues?
Any guidance or code examples would be greatly appreciated!
The easiest way:
public class SampleEclipseStoreTest
{
@TempDir
Path location;
@Test
void saveAndLoadTest()
{
List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
try (EmbeddedStorageManager storageManager = EmbeddedStorage.start(list, location)) {
}
try (EmbeddedStorageManager storageManager = EmbeddedStorage.start(location)) {
List<String> loaded = (List<String>) storageManager.root();
assertIterableEquals(list, loaded);
}
}
}
Eclipse-store is autoclosable.
Junit has an annotation @TempDir. The files are removed after test.
4
Moving the storage manager setup inside of the test seems to have solved it. I also removed the test/resources/application.properties file since it doesn’t seem necessary.
@Tag("database")
class EclipseProjectAdapterTest {
private EclipseProjectAdapter adapter;
@TempDir
Path storageDir;
private static final Logger log = LoggerFactory.getLogger(EclipseProjectAdapterTest.class);
@Test
void canWriteReadRestartAndReadAgain() {
writeData();
log.info("Storage manager shut down. Restarting...");
readData();
}
private void writeData() {
try (EmbeddedStorageManager storageManager = startStorageManager()) {
adapter = new EclipseProjectAdapter(storageManager);
List<Project> projects = adapter.findAll();
assertThat(projects).isEmpty();
Project project = Project.create("Project A");
adapter.save(project);
List<Project> allProjects = adapter.findAll();
assertThat(allProjects).hasSize(1);
assertThat(allProjects.getFirst().name()).isEqualTo("Project A");
}
}
private void readData() {
try (EmbeddedStorageManager storageManager = startStorageManager()) {
adapter = new EclipseProjectAdapter(storageManager);
List<Project> allProjects = adapter.findAll();
assertThat(allProjects).hasSize(1);
assertThat(allProjects.getFirst().name()).isEqualTo("Project A");
}
}
private EmbeddedStorageManager startStorageManager() {
return EmbeddedStorage.start(storageDir);
}
public class EclipseProjectAdapter implements ProjectRepository {
private final EmbeddedStorageManager storageManager;
public EclipseProjectAdapter(EmbeddedStorageManager storageManager) {
this.storageManager = storageManager;
initializeRoot();
}
private void initializeRoot() {
if (storageManager.root() == null) {
storageManager.setRoot(new DataRoot());
storageManager.storeRoot();
}
}
@Write
@Override
public void save(Project project) {
DataRoot root = (DataRoot) storageManager.root();
root.projects().add(project);
saveWithEagerStoring(root); // Use eager storer for at least this save operation to ensure persistence
}
@Read
@Override
public List<Project> findAll() {
DataRoot root = (DataRoot) storageManager.root();
return new ArrayList<>(root.projects().all());
}
@Read
@Override
public Optional<Project> findByName(String projectName) {
List<String> allNames = findAllNames();
String cleanedName = ProjectNameMatcher.from(projectName, allNames).orElse(null);
if (cleanedName == null) return Optional.empty();
DataRoot root = (DataRoot) storageManager.root();
return Optional.ofNullable(root.projects().byName(projectName));
}
@Read
@Override
public List<String> findAllNames() {
DataRoot root = (DataRoot) storageManager.root();
return new ArrayList<>(root.projects().getAllNames());
}
private void saveWithEagerStoring(DataRoot root) {
Storer eagerStorer = storageManager.createEagerStorer();
eagerStorer.store(root);
eagerStorer.commit();
}
}