动态添加属性源到 SpringBootTest

Arc*_*ano 6 java testing spring spring-boot

类似于Springboot 单元测试集 @Configuration Properties 动态但上下文不同。

在我的情况下,我有一个TestContainer运行一个自定义的 MySQL 数据库,该数据库预先填充了大量数据(不使用 SQL 批量加载方法,因为数据是生产的匿名副本,并且通过 SQL 执行它使容器的启动时间20 分钟对 2 分钟)。

到目前为止,我的测试看起来像这样

@RunWith(SpringRunner.class)
@SpringBootTest(
    classes = {
        Bootstrap.class
    }
)
public class ITFakeDB {
    @ClassRule
    public static final GenericContainer DB = new GenericContainer("devdb")
        .withExposedPorts(3306);
    @Autowired
    private DataSource dataSource;

    @Autowired
    private Users users;

    @Test
    public void testDatabaseIsUp() {
        assertTrue(DB.getMappedPort(3306) != 0);
    }

    @Test
    public void testUser() {
        Optional<User> user = users.findByLoginName("mimi");
        assertTrue(users.isPresent());
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是以某种方式将spring.datasource.url(或在我的情况下,datasources.schema1.url因为我做了路由数据源)设置为DB

小智 5

您可以使用ContextConfiguration和手动覆盖 Spring-boot 测试中的属性ApplicationContextInitializer

覆盖属性 - 定义一个静态内部类:

  static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
      String url = "jdbc:mysql://" + DB.getContainerIpAddress() + ":" + DB.getMappedPort(3306) + "/my_db";

      TestPropertyValues
          .of("datasources.schema1.url=" + url)
          .applyTo(configurableApplicationContext.getEnvironment());
    }
  }

Run Code Online (Sandbox Code Playgroud)

注意:我假设url是从 ip 地址、端口和数据库名称派生的。您可以根据需要更改该部分,但核心思想仍然存在。

ApplicationContextInitializer可用于在上下文刷新之前以编程方式初始化 Spring 上下文。现在,通过在测试类级别使用ContextConfiguration以下注释来连接上下文初始值设定项类:

@ContextConfiguration(initializers = Initializer.class)
Run Code Online (Sandbox Code Playgroud)

文档:

应用上下文初始化器

上下文配置