title: How to use testcontainers in existing application?
body: <p><strong>CONTEXT:</strong></p>
  
  <p>I have an existing Camel application. In order to test it with Spring Boot tools, it is wrapped into the Spring Boot framework and all tests run against this <code>Spring Boot</code> app. Important: This code is used in production, so I am not allowed to change implementation and rewrite tests altogether. To test the app in a prod-like environment I use <code>testcontainers</code> and Microsoft SQL Server in Docker, it is an additional functional tests module.</p>
  
  <p>What I am trying to do is to spin up <code>testcontainers</code> and update <code>DataSource</code>, so it will point to SQL Server endpoint. I bumped into a never-ending series of problems. What am I doing wrong?</p>
  
  <p><strong>PROBLEM:</strong></p>
  
  <p>My <code>SpringBootTestApplication</code> looks:</p>
  
  <pre><code>@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);
      }
  }
  </code></pre>
  
  <p>My test looks this way:</p>
  
  <pre><code>@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
      }
  
  }
  </code></pre>
  
  <p>I am trying to dynamically load <code>DataSource</code> into a test, so I will test against MS SQL Server, not against default in-memory configuration.</p>
  
  <p>The issue is that I don't know the configuration of MS SQL Server Docker container until it started and I cannot dynamically inject my own DataSource implementation.</p>
  
  <p><strong>LIST OF ATTEMPTED SOLUTIONS:</strong></p>
  
  <ul>
  <li>Dynamically configure DataSource</li>
  <li>Redefine default @Bean in Configuration and load with @Import</li>
  <li>Create additional bean with different Qualifier</li>
  <li>Use <code>BeanPostProcessor</code> to reload beans</li>
  </ul>
  
  <p>None of the above solutions work. It seems that I do something wrong and got lost between three birches. What am I doing wrong?</p>