Java 如何在现有应用程序中使用testcontainers?
上下文: 我有一个现有的Camel应用程序。为了用Spring Boot工具测试它,它被包装到Spring Boot框架中,所有测试都针对这个Java 如何在现有应用程序中使用testcontainers?,java,spring-boot,testcontainers,Java,Spring Boot,Testcontainers,上下文: 我有一个现有的Camel应用程序。为了用Spring Boot工具测试它,它被包装到Spring Boot框架中,所有测试都针对这个Spring Bootapp运行。重要提示:此代码用于生产,因此不允许我更改实现和重写测试。为了在类似产品的环境中测试应用程序,我使用Docker中的testcontainers和Microsoft SQL Server,它是一个附加的功能测试模块 我试图做的是启动testcontainers并更新DataSource,这样它将指向SQL Server端点
Spring Boot
app运行。重要提示:此代码用于生产,因此不允许我更改实现和重写测试。为了在类似产品的环境中测试应用程序,我使用Docker中的testcontainers
和Microsoft SQL Server,它是一个附加的功能测试模块
我试图做的是启动testcontainers
并更新DataSource
,这样它将指向SQL Server端点。我遇到了一系列没完没了的问题。我做错了什么
问题:
我的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
}
}
我正在尝试将数据源
动态加载到测试中,因此我将针对MS SQL Server进行测试,而不是针对默认的内存配置
问题是,在MS SQL Server Docker容器启动之前,我不知道它的配置,并且我无法动态注入自己的数据源实现
尝试的解决方案列表:
- 动态配置数据源
- 在配置中重新定义默认@Bean,并使用@Import加载
- 使用不同的限定符创建其他bean
- 使用
重新加载beanBeanPostProcessor
最后但并非最不重要的一点是,如果您只需要一个SQL数据库,那么您可以使用。您可以添加关于出错原因的信息吗?@blackrain问题是,
数据源
来自@Bean
,在测试中不会被替换。换句话说,SpringBoot配置了Derby
,当我试图用Microsoft SQL Server替换它时,它仍然是Derby
。对不起,我误解了这个问题。我可能帮不上忙。乍一看,如果您使用的是嵌入式derby,那么您似乎不需要mssql testcontainer。您可能只需要从测试中设置应用程序所需的属性值,将.sql文件放入测试并运行它。就像我说的,我从来没有做过这样的事。