如何在现有应用程序中使用测试容器?
How to use testcontainers in existing application?
上下文:
我有一个现有的 Camel 应用程序。为了使用 Spring 引导工具对其进行测试,它被包装到 Spring 引导框架中,并针对此 Spring Boot
应用程序进行所有测试 运行。重要提示:此代码用于生产,因此不允许我更改实现和完全重写测试。为了在类似产品的环境中测试应用程序,我在 Docker 中使用 testcontainers
和 Microsoft SQL Server,它是一个额外的功能测试模块。
我想做的是启动 testcontainers
并更新 DataSource
,因此它将指向 SQL 服务器端点。我遇到了一系列没完没了的问题。我做错了什么?
问题:
我的SpringBootTestApplication
长相:
@SpringBootApplication
public class SpringBootTestApplication {
@Bean(name = "myDataSource")
public DataSource dataSource() throws ClassNotFoundException {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(Class.forName("org.apache.derby.jdbc.EmbeddedDriver").asSubclass(Driver.class));
dataSource.setUrl("jdbc:derby:memory:testdb;create=true");
dataSource.setUsername("sa");
dataSource.setPassword("");
Resource initSchema = new ClassPathResource("db/schema.sql");
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema);
databasePopulator.setIgnoreFailedDrops(true);
DatabasePopulatorUtils.execute(databasePopulator, dataSource);
return dataSource;
}
public static void main(String[] args) {
SpringApplication.run(SpringBootTestApplication.class, args);
}
}
我的测试是这样的:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootTestApplication.class)
@TestPropertySource("classpath:application-test.properties")
public class LargeDatabaseRetrieverTest {
@Rule
public MSSQLServerContainer mssqlServerContainer = (MSSQLServerContainer) new MSSQLServerContainer()
.withInitScript("db/test-data-mssql.sql")
.withExposedPorts(1433);
@Autowired
@Qualifier("myDataSource")
private DataSource dataSource;
@Before
public void setUp() throws Exception {
mssqlServerContainer.start();
DataSource mssqlDataSource = configureDataSource();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(mssqlDataSource);
}
@After
public void tearDown() throws Exception {
mssqlServerContainer.stop();
}
private DataSource configureDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(mssqlServerContainer.getDriverClassName());
basicDataSource.setUrl(mssqlServerContainer.getJdbcUrl());
basicDataSource.setUsername(mssqlServerContainer.getUsername());
basicDataSource.setPassword(mssqlServerContainer.getPassword());
return basicDataSource;
}
@Test
public void test() {
// Use DataSource in here
}
}
我正在尝试将 DataSource
动态加载到测试中,因此我将针对 MS SQL 服务器进行测试,而不是针对默认的内存配置。
问题是我不知道 MS SQL 服务器 Docker 容器的配置,直到它启动,我无法动态注入我自己的 DataSource 实现。
尝试过的解决方案列表:
- 动态配置数据源
- 在Configuration中重新定义默认的@Bean并使用@Import加载
- 使用不同的限定符创建额外的 bean
- 使用
BeanPostProcessor
重新加载bean
None 上述解决方案有效。好像我做错了什么,在三棵桦树之间迷了路。我做错了什么?
你检查过Spring Boot's docs on how to use it with Testcontainers? Or Testcontainers' Spring Boot example了吗?
还有a workshop.
最后但同样重要的是,如果你只需要一个SQL数据库,你可以使用the JDBC URL support.
上下文:
我有一个现有的 Camel 应用程序。为了使用 Spring 引导工具对其进行测试,它被包装到 Spring 引导框架中,并针对此 Spring Boot
应用程序进行所有测试 运行。重要提示:此代码用于生产,因此不允许我更改实现和完全重写测试。为了在类似产品的环境中测试应用程序,我在 Docker 中使用 testcontainers
和 Microsoft SQL Server,它是一个额外的功能测试模块。
我想做的是启动 testcontainers
并更新 DataSource
,因此它将指向 SQL 服务器端点。我遇到了一系列没完没了的问题。我做错了什么?
问题:
我的SpringBootTestApplication
长相:
@SpringBootApplication
public class SpringBootTestApplication {
@Bean(name = "myDataSource")
public DataSource dataSource() throws ClassNotFoundException {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(Class.forName("org.apache.derby.jdbc.EmbeddedDriver").asSubclass(Driver.class));
dataSource.setUrl("jdbc:derby:memory:testdb;create=true");
dataSource.setUsername("sa");
dataSource.setPassword("");
Resource initSchema = new ClassPathResource("db/schema.sql");
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema);
databasePopulator.setIgnoreFailedDrops(true);
DatabasePopulatorUtils.execute(databasePopulator, dataSource);
return dataSource;
}
public static void main(String[] args) {
SpringApplication.run(SpringBootTestApplication.class, args);
}
}
我的测试是这样的:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootTestApplication.class)
@TestPropertySource("classpath:application-test.properties")
public class LargeDatabaseRetrieverTest {
@Rule
public MSSQLServerContainer mssqlServerContainer = (MSSQLServerContainer) new MSSQLServerContainer()
.withInitScript("db/test-data-mssql.sql")
.withExposedPorts(1433);
@Autowired
@Qualifier("myDataSource")
private DataSource dataSource;
@Before
public void setUp() throws Exception {
mssqlServerContainer.start();
DataSource mssqlDataSource = configureDataSource();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(mssqlDataSource);
}
@After
public void tearDown() throws Exception {
mssqlServerContainer.stop();
}
private DataSource configureDataSource() {
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName(mssqlServerContainer.getDriverClassName());
basicDataSource.setUrl(mssqlServerContainer.getJdbcUrl());
basicDataSource.setUsername(mssqlServerContainer.getUsername());
basicDataSource.setPassword(mssqlServerContainer.getPassword());
return basicDataSource;
}
@Test
public void test() {
// Use DataSource in here
}
}
我正在尝试将 DataSource
动态加载到测试中,因此我将针对 MS SQL 服务器进行测试,而不是针对默认的内存配置。
问题是我不知道 MS SQL 服务器 Docker 容器的配置,直到它启动,我无法动态注入我自己的 DataSource 实现。
尝试过的解决方案列表:
- 动态配置数据源
- 在Configuration中重新定义默认的@Bean并使用@Import加载
- 使用不同的限定符创建额外的 bean
- 使用
BeanPostProcessor
重新加载bean
None 上述解决方案有效。好像我做错了什么,在三棵桦树之间迷了路。我做错了什么?
你检查过Spring Boot's docs on how to use it with Testcontainers? Or Testcontainers' Spring Boot example了吗?
还有a workshop.
最后但同样重要的是,如果你只需要一个SQL数据库,你可以使用the JDBC URL support.