类似于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
答案 0 :(得分:2)
您可以使用ContextConfiguration
和ApplicationContextInitializer
在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)
文档:
答案 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;
/
查看详细信息: