在SpringBoot中填充MongoDB TestContainers以进行集成测试

m528fe3b  于 2022-10-23  发布在  Spring
关注(0)|答案(3)|浏览(165)

我的问题类似于Populate a database with TestContainers in a SpringBoot integration test,但我有一个mongo db测试容器,如下所示:

@Container
private static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:3.4.20"))

我可以使用mongorepository.save(),但这实际上并不可行,因为有多个集合,我需要填充几个字段(其中许多是嵌套字段)。还有什么其他方法可以达到同样的效果呢?

w6mmgewl

w6mmgewl1#

我不是MongoDBMaven,但您应该独立于使用TestContainers来装备数据库这一事实来填充数据库。因此,使用存储库似乎是正确的。您还可以在测试类中使用特殊的存储库,您可以向其中添加执行更大引导的方法。
另外,考虑停止使用@Container注解,它为每个测试类启动一个容器,这可能会导致大量的启动开销。通常,使用Singleton Container模式会带来更好的测试套件性能。

pkmbmrz7

pkmbmrz72#

有一个liquibase mongodb项目可以使用。你可以看看这个project。有一个db.changelog-master.json,其中模式创建被定义为第一个ChangeLog(您可以定义更多),正如您在刚刚定义容器的test中看到的那样,设置spring.data.mongodb.uri并手动运行迁移,因为Spring Boot没有为LiqueBase 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的。
另外,请检查Initializing a fresh instance

atmip9wb

atmip9wb3#

过去,当我需要数据库中的一些初始数据时,我的一种方法是添加一个ApplicationConextInitializer,它引导测试容器,然后在容器内运行mongoRestore,以加载我单独准备的mongoump。
这样,您就可以将转储文件夹保存在测试资源文件夹中。当然,如果您在那里有其他文件,请确保使用正确的类路径资源路径。
希望这个能帮上忙!

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;
        }
    }
}

相关问题