简体   繁体   中英

Second datasource in spring application.properties for tests?

I have datasource defined in my application.properties as Oracle database and that's ok, the controller & repository work fine, I can persist entities and fetch database records.

I have integration tests written. Before I connected my app with database I created some objects and persisted them in @PostConstruct method - and that was ok. But now, when I connected everything with database, my tests try to fetch records from the table which is pretty large. I think that's due to my application.properties file in which defined datasource is Oracle database.

spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@blabla
spring.datasource.username=blabla
spring.datasource.password=blabla
spring.jpa.hibernate.ddl-auto=none
spring.jpa.generate-ddl=false

I want to carry on tests using some in-memory HSQL , not real database. But I still want my controller and repository to use the real one. How can I do it? Is there any possibility to add second datasource in application.properties? Or maybe an easier solution?

In Spring 4 you have @Profile annotation so you can use its advantage. Create another like application-test.properties file with it's own properties.

Create configuration for your tests:

@Configuration
@Profile("test") 
public class TestConfiguration {
    ....
}

Then annotate your class with @ActiveProfiles annotation:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
@ActiveProfiles("test")
public class TestRepository {
   ...
}

There are many ways to achieve this, one way is to use Spring profiles. The test profile would use a different properties file than the production one.

Spring has org.springframework.mock.jndi.SimpleNamingContextBuilder package that allows you to bind the dataSource programatically.

Sample Test class that I use:

public class MockJNDIContext {

    @BeforeClass
    public static void setUpClass() throws Exception {

        SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
        OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();//Use your own Connection Pool DS here as you require
        ds.setURL("jdbc:oracle:thin:@10.xxx.xxx.xx:9999:SID");
        ds.setUser("USER");
        ds.setPassword("PASSWORD");
        //Bind it to the JNDI you need
        builder.bind("java:comp/env/jdbc/MY/APP", ds);

    }

    @Test
    public void test(){
        System.out.println("JNDI Initialized");
    }

}

Suite Class:

@RunWith(Suite.class)
@Suite.SuiteClasses({
        MockJNDIContext.class,
        InitializeTestConfig.class
})
public class ServiceSuite{
}

May be this helps? If you are trying to load from one more application.props, use one more class ( InitializeTestConfig.class ) that initializes and passes the DS args and add to suite as mentioned above and try?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM