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");
}
}
Spring is a framework. A framework calls you, so by definition, using spring with your controller is an integration point and does not belong in a unit test.
Spring Boot will automatically find and load application. properties and application. yaml files from the following locations when your application starts: The classpath root.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With