Hel*_*rld 8 java spring junit4 spring-boot testcontainers
使用 Spring 进行集成测试,我可以填充运行脚本的测试数据库,如下所示......
@Test
@Sql({"/db/schema.sql", "/db/accountConfig.sql", "/db/functions/fnSomething.sql"})
public void verifySomething() {
...
}
Run Code Online (Sandbox Code Playgroud)
但是,我想.sql
在任何测试运行之前只运行一次所有文件。JUnit 4 是否有方法可以做到这一点?似乎@Sql
只针对带有 @Test 注释的方法运行。
我正在使用 Junit 4、Spring Boot、Java 15、Testcontainers。
我尝试过的事情...
@BeforeClass
在我的测试类扩展的类上使用,但它似乎在我的测试后运行。ScriptUtils.executeSqlScript
,但由于某种原因,测试容器不喜欢这样。这是我的示例代码,适用于@Sql
但不适用于ScriptUtils.executeSqlScript
.
@ContextConfiguration(initializers = AbstractIntegrationTest.Initializer.class)
public abstract class AbstractIntegrationTest {
@ClassRule
public static MSSQLServerContainer mssqlserver = new MSSQLServerContainer();
public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
Properties props = new Properties();
props.put("spring.datasource.driver-class-name", mssqlserver.getDriverClassName());
props.put("spring.datasource.url", mssqlserver.getJdbcUrl());
props.put("spring.datasource.username", mssqlserver.getUsername());
props.put("spring.datasource.password", mssqlserver.getPassword());
environment
.getPropertySources()
.addFirst(new PropertiesPropertySource("myTestDBProps", props));
configurableApplicationContext.setEnvironment(environment);
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试类只是扩展AbstractIntegrationTest
。但@Sql
对每个测试用例都使用运行脚本。有人建议更好的方式来初始化 SQL 脚本吗?尝试了flyway,但它不允许从脚本创建数据库。
Nik*_*las 11
我建议查看在 Spring 上下文初始化时执行一次 SQL 脚本的数据库初始化程序 bean。基本上,有两种解决方案,具体取决于您使用 JDBC 还是 R2DBC。由于您想要初始化多个脚本,因此您应该使用CompositeDatabasePopulator
. 还要记住导入正确的类,因为它们具有相同的名称,但来自不同的包,这同样取决于 JDBC/R2DBC。
要从resources
文件夹加载资源,请随意使用以下选项之一:
Resource resource = new ClassPathResource("sql/schema.sql"))
@Value("classpath:sql/schema.sql") Resource resource
这个解决方案相当灵活,因为您可以使用以下命令为测试上下文定义初始化程序 bean @TestConfiguration
(请记住使用此注释有点棘手,因此我建议您参阅这篇文章:Quirks of Spring's @TestConfiguration对我帮助很大)。
该解决方案应该适用于任何可用的解决方案,ConnectionFactory
包括测试容器。
org.springframework.jdbc.datasource.init.CompositeDatabasePopulator
org.springframework.jdbc.datasource.init.ResourceDatabasePopulator
通过调用进行的初始化populate
必须发生在@PostConstuct
Spring Boot 自动不会检测到填充器的情况下。我建议将以下代码片段包装在配置类中并将其包含在测试范围中。
@Autowired
private DataSource dataSource;
@PostConstruct
public void initData() throws SQLException {
var populator = new CompositeDatabasePopulator();
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/schema.sql")));
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/catalog.sql")));
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/data.sql")));
populator.populate(dataSource.getConnection());
}
Run Code Online (Sandbox Code Playgroud)
org.springframework.r2dbc.connection.init.CompositeDatabasePopulator
org.springframework.r2dbc.connection.init.ResourceDatabasePopulator
ConnectionFactoryInitializer
当 Spring 上下文加载时,您可以使用它来初始化添加到此初始值设定项的所有填充器。
@Bean
public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
var populator = new CompositeDatabasePopulator();
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/schema.sql")));
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/catalog.sql")));
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("sql/data.sql")));
var initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
initializer.setDatabasePopulator(populator);
return initializer;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4707 次 |
最近记录: |