КОНТЕКСТ:
У меня уже есть приложение Camel. Чтобы протестировать его с помощью инструментов Spring Boot, он заключен в среду Spring Boot, и все тесты выполняются с этим приложением Spring Boot
. Важно: этот код используется в производственной среде, поэтому мне не разрешено полностью изменять реализацию и переписывать тесты. Чтобы протестировать приложение в производственной среде, я использую testcontainers
и Microsoft SQL Server в Docker, это дополнительный модуль функциональных тестов.
То, что я пытаюсь сделать, это раскрутить 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 Server Docker до его запуска, и я не могу динамически внедрить свою собственную реализацию DataSource.
СПИСОК ПЫТАЕМЫХ РЕШЕНИЙ:
- Динамически настроить источник данных
- Переопределить @Bean по умолчанию в конфигурации и загрузить с помощью @ Import
- Создать дополнительный bean с другим квалификатором
- Используйте
BeanPostProcessor
для перезагрузки bean
Ни одно из вышеперечисленных решений не работает. Похоже, я что-то не так и заблудился между трех берез. Что я делаю не так?