我的问题类似于在 SpringBoot 集成测试中使用 TestContainers 填充数据库,但我有一个 mongo db 测试容器,如下所示:
@Container
private static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:3.4.20"))
我可以使用 mongorepository.save() 但这并不是真正可行,因为有多个集合并且我需要填充多个字段(其中一堆是嵌套字段)。还有哪些其他方法可以达到同样的效果?
过去,当我需要数据库中的一些初始数据时,我的一种方法是添加一个 ApplicationContextInitializer 来启动 testcontainer,然后在容器内运行 mongorestore 以加载我单独准备的 mongodump。
这样您就可以将转储文件夹保留在测试资源文件夹中。 当然,如果您有其他文件,请务必使用正确的类路径资源路径。
希望这有帮助!
public class TestContainerInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@SneakyThrows
@Override
public void initialize(ConfigurableApplicationContext context) {
MongoDBContainer instance = MongoContainerSingleton.getInstance();
instance.copyFileToContainer(
MountableFile.forClasspathResource("/"), "/IT-dump");
Container.ExecResult mongorestore = instance.execInContainer("mongorestore", "/IT-dump/dump/");
}
public static class MongoContainerSingleton {
private static volatile MongoDBContainer instance = null;
public static MongoDBContainer getInstance() {
synchronized (MongoContainerSingleton.class) {
if (instance == null) {
instance = new MongoDBContainer("mongo:4.2.11")
.withReuse(true);
instance.start();
}
}
return instance;
}
}
}
有一个liquibase mongodb项目可以使用。你可以看看这个项目。有一个 db.changelog-master.json,其中模式创建被定义为第一个变更日志(您可以定义更多),正如您在刚刚定义容器的 test 中看到的那样,设置
spring.data.mongodb.uri
并手动由于 Spring Boot 不提供 liquibase mongodb 扩展的自动配置,因此运行迁移。
@Container
private static final MongoDBContainer mongo = new MongoDBContainer("mongo:4.0.10");
@Autowired
private PersonRepository repository;
@DynamicPropertySource
static void mongoProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.mongodb.uri", mongo::getConnectionString);
}
@Test
void test() throws LiquibaseException {
var database = (MongoLiquibaseDatabase) DatabaseFactory.getInstance().openDatabase(mongo.getReplicaSetUrl("test"), null, null, null, null);
var liquibase = new Liquibase("db/changelog/db.changelog-master.json", new ClassLoaderResourceAccessor(), database);
liquibase.update("");
var books = this.repository.findAll();
assertThat(books).hasSize(3);
}
这个示例项目也是基于 Spring Boot 的。
另外,请检查初始化新实例
我不是 MongoDB 专家,但您应该独立于您使用 Testcontainers 来检测数据库的事实来填充数据库。所以使用存储库似乎是正确的。您还可以在测试类中使用特殊的存储库,向其中添加执行更大引导的方法。
此外,请考虑停止使用
@Container
注释,它会为每个测试类启动一个容器,这可能会导致大量的启动开销。一般来说,使用单例容器模式会带来更好的测试套件性能。