5

I use spring boot for my project. When i run my app everthing is OK by if i run my unit test (@RunWith(SpringJUnit4ClassRunner)), i got below error. I don't know why spring didn't use application.properties in unit test(which data source parameters defined).

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
    ... 106 more
Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
    at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:236)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:176)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:43)
    at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 107 more

my unit test class is :

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class)
public class RepoTest {

    @Autowired IRepo repo;

    @Test
    public void listCards() {
        repo.findCardNo(1L, "00981231231");
    }

}
Mojtaba Asgari
  • 1,242
  • 1
  • 13
  • 24

3 Answers3

6

You can try @TestPropertySource and add specific file. This way you can have different properties for test and for the real app.

You can use @TestPropertySource to override values in application.properties. From its javadoc:

test property sources can be used to selectively override properties defined in system and application property sources

For example:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class)
@TestPropertySource(locations="classpath:test.properties")
public class RepoTest {

Also for unit testing you might consider mocking the database knowing the correct response. First the unit tests will work faster. Also your unit tests shouldn't fail depending on external service (database) because the code works properly even if the database is offline.

Then you can make some more complex integration tests that actually connect to a database.

Veselin Davidov
  • 7,031
  • 1
  • 15
  • 23
5

Use @SpringBootTest instead of ContextConfiguration the SpringBootTest adds some more magic, and will load the entire configuration and for all intents and purpose the boot application too. Context Configuration will just load up a Spring context without a lot of the Spring Boot magic.

Darren Forsythe
  • 10,712
  • 4
  • 43
  • 54
1

I think use @SpringBootTest is an overkill for repo test. Spring has @DatajpaTest for testing persistence layer. It automatically loads the persistence beans into context and you will get everything ready in persistence layer to @Autowire.

J.Luan
  • 227
  • 2
  • 5