在 SpringBoot 中填充 MongoDb TestContainer 进行集成测试

问题描述 投票:0回答:3

我的问题类似于在 SpringBoot 集成测试中使用 TestContainers 填充数据库,但我有一个 mongo db 测试容器,如下所示:

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

我可以使用 mongorepository.save() 但这并不是真正可行,因为有多个集合并且我需要填充多个字段(其中一堆是嵌套字段)。还有哪些其他方法可以达到同样的效果?

spring-boot spring-data-mongodb spring-test testcontainers
3个回答
3
投票

过去,当我需要数据库中的一些初始数据时,我的一种方法是添加一个 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;
        }
    }
}

1
投票

有一个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 的。

另外,请检查初始化新实例


0
投票

我不是 MongoDB 专家,但您应该独立于您使用 Testcontainers 来检测数据库的事实来填充数据库。所以使用存储库似乎是正确的。您还可以在测试类中使用特殊的存储库,向其中添加执行更大引导的方法。

此外,请考虑停止使用

@Container
注释,它会为每个测试类启动一个容器,这可能会导致大量的启动开销。一般来说,使用单例容器模式会带来更好的测试套件性能。

© www.soinside.com 2019 - 2024. All rights reserved.