Spring Boot中如何测试基于EmbeddedStorageManager的EclipseStore?
EclipseStore 1.4.0 + Spring Boot 3.3 测试环境配置问题
我正在开发基于Java 21、Spring Boot 3.3、Vaadin 24的应用,使用EclipseStore 1.4.0实现嵌入式存储,生产环境配置正常,但在搭建测试验证与EclipseStore的EmbeddedStorageManager交互的EclipseProjectAdapter类时遇到困难,希望使用内存或临时存储避免影响生产数据库。
已尝试的配置
测试类
@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"); } }
测试配置类
@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}
错误信息
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.
已尝试的解决方法
- 在pom.xml中引入
eclipsestore-spring-boot-starter依赖; - 在
TestConfig中显式定义EclipseStoreProperties、EmbeddedStorageManagerFactory和EmbeddedStorageFoundationFactoryBean; - 验证EclipseStore自动配置已启用;
- 检查测试配置文件是否正确设置临时存储目录。
问题
- 如何配置Spring Boot测试以使用EclipseStore的内存或临时存储?
- 是否可以使用TestContainers或类似工具进行EclipseStore测试?
- 有没有EclipseStore测试的最佳实践或示例可解决这些问题?
解决方案
1. 配置内存/临时存储的正确方式
核心问题是@SpringBootTest(classes = TestConfig.class)仅加载测试配置,未触发EclipseStore的自动配置,导致EclipseStoreProperties等Bean缺失。以下是两种可行配置方式:
方式一:内存存储(推荐用于单元测试)
直接创建内存模式的EmbeddedStorageManager,无需依赖自动配置组件:
@Configuration public class TestConfig { @Bean @Primary public EmbeddedStorageManager inMemoryEmbeddedStorageManager() { // 创建内存文件系统的存储管理器,完全不占用磁盘空间 return EmbeddedStorage.Foundation() .setConfiguration(EmbeddedStorageConfiguration.Builder() .setStorageFileSystem(MemoryFileSystem.New()) .build()) .createEmbeddedStorageManager() .start(); } }
修改测试类,让Spring加载主应用配置+测试配置(确保自动配置生效,主应用类需标注@SpringBootApplication):
@SpringBootTest(classes = {YourMainApplication.class, TestConfig.class}) @Tag("database") class EclipseProjectAdapterTest { // 剩余代码保持不变 }
方式二:临时磁盘存储(用于模拟生产环境的集成测试)
通过自动配置的EclipseStoreProperties修改存储目录,同时确保自动配置被加载:
@Configuration @EnableAutoConfiguration public class TestConfig { @Bean @Primary EmbeddedStorageManager tempDirStorageManager(EclipseStoreProperties properties, EmbeddedStorageManagerFactory managerFactory, EmbeddedStorageFoundationFactory foundationFactory) { // 生成唯一临时目录 String tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "test-store-" + UUID.randomUUID()) .toString(); properties.setStorageDirectory(tempDir); EmbeddedStorageFoundation<?> foundation = foundationFactory.createStorageFoundation(properties); EmbeddedStorageManager manager = managerFactory.createStorage(foundation, false); // 测试后自动删除临时目录 Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { FileUtils.deleteDirectory(new File(tempDir)); } catch (IOException e) { e.printStackTrace(); } })); return manager; } }
2. TestContainers的适用性
EclipseStore是嵌入式本地存储,无需依赖外部服务,TestContainers并非必需。如果要模拟隔离的磁盘环境,直接使用JDK的临时目录或内存文件系统即可,比TestContainers更轻量高效。
3. EclipseStore测试最佳实践
- 单元测试用内存存储:速度快、无副作用,适合验证业务逻辑与存储交互的正确性;
- 集成测试用临时磁盘存储:模拟生产环境的磁盘IO行为,测试后自动清理目录;
- 使用
@DirtiesContext:如果测试之间需要隔离存储状态,在测试类上添加@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD),确保每个测试都有干净的存储环境; - 测试前后清理状态:在
@AfterEach中调用storageManager.shutdown(),并删除临时目录(如果使用磁盘存储); - 复用存储配置:将测试存储配置抽成单独的
@Configuration类,供多个测试类复用。
内容的提问来源于stack exchange,提问作者Nathan Lively
相关产品推荐
相关产品推荐

