【问题标题】:Populate MongoDb TestContainers in a SpringBoot for integration test在 SpringBoot 中填充 MongoDb TestContainers 以进行集成测试
【发布时间】:2022-10-21 21:25:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: spring-boot spring-data-mongodb spring-test testcontainers


    【解决方案1】:

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

    另外,考虑停止使用 @Container 注释,它会为每个测试类启动一个容器,这会导致大量的启动开销。通常,使用Singleton Container Pattern 会导致更好的测试套件性能。

    【讨论】:

      【解决方案2】:

      有一个可以使用的liquibase mongodb 项目。你可以看看这个project。有一个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。

      另外,检查Initializing a fresh instance

      【讨论】:

      • 我会好好检查的,谢谢!但是有没有办法我可以在这个容器中创建一个集合并从我已经拥有的一些现有数据库中插入 json 文档?我正在尝试做一些兼容性工作,所以我的理想方案是使用一些现有数据库中的一些文档并将其插入此容器中以进行测试。
      • 我已经更新了指向 mongo docker 文档的答案,您可以在其中使用 /docker-entrypoint-initdb.d 复制 sh 或 js 文件
      【解决方案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;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-02
        • 2019-09-19
        • 2020-08-10
        • 2017-12-19
        • 2021-08-05
        • 2016-05-02
        • 2019-09-06
        • 2020-04-02
        • 1970-01-01
        相关资源
        最近更新 更多