动态添加属性源到SpringBootTest

时间:2019-05-18 15:18:20

标签: java spring spring-boot testing

类似于Springboot unit test set @Configuration Properties dynamically,但上下文不同。

在我的情况下,我有一个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());
    }
}

我想做的是将spring.datasource.url(或者在我的情况下为datasources.schema1.url,因为我做了routing datasource)设置为DB

2 个答案:

答案 0 :(得分:2)

您可以使用ContextConfigurationApplicationContextInitializer在Spring-boot测试中手动覆盖属性。

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

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

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

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

@ContextConfiguration(initializers = Initializer.class)

文档:

ApplicationContextInitializer

ContextConfiguration

答案 1 :(得分:1)

虽然前面的答案应该起作用,但是Spring Framework 5.2.5(包含在Spring Boot 2.2.6中)已经针对这种情况引入了新的@DynamicPropertySource static void initializeDatasource(DynamicPropertyRegistry registry) { String ip = DB.getContainerIpAddress(); Integer port = DB.getMappedPort(3306); String url = String.format("jdbc:mysql://%s:%d/my_db", ip, port); registry.add("datasources.schema1.url", url); } 注释:

create table dep_emp_ast(
cod_dep number(3),
cod_ang number(3));



declare
  type tab_imb is table of dept_ast.department_id%type;
  t tab_imb:=tab_imb();
  v_ang emp_ast.employee_id%type;
begin
  select distinct department_id
  bulk collect into t
  from dept_ast;
    forall i in 1..t.count 
    for j in (select employee_id
                      from emp_ast
                      where department_id=t(i)) loop
      insert into dep_emp_ast
      values(t(i),j.employee_id);
      exit when sql%notfound;
      dbms_output.put_line('Au fost introdusi '||sql%bulk_rowcount(i));
  end loop;
end;
/

查看详细信息: