6

I am trying to write some tests for my application and encountered following problem: I defined a application-test.yml with folling content:

server:
  port: 8085

spring:
    security:
        oauth2:
            resourceserver:
                jwt:
                    # change localhost:8081 with container name
                    issuer-uri: http://localhost:8081/auth/realms/drivingschool
                    jwk-set-uri: http://localhost:8081/auth/realms/drivingschool/protocol/openid-connect/certs

keycloak:
    realm: drivingschool
    auth-server-url: http://localhost:8081/auth
    ssl-required: external
    resource: client-interface
    use-resource-role-mappings: true
    credentials:
        secret: xxx
    bearer-only: true

My test class:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
public class StudentControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private StudentService service;

    @MockBean
    private StudentRepository repository;

    @Test
    public void contextLoads(){}
//more tests
}

the test all pass green BUT in the log i can see, that my app tries to connect to a database configured in my (basic) application.yml.

ava.sql.SQLNonTransientConnectionException: Could not connect to address=(host=localhost)(port=9005)(type=master) : Socket fail to connect to host:localhost, port:9005. Verbindungsaufbau abgelehnt (Connection refused)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:73) ~[mariadb-java-client-2.6.1.jar:na]
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:192) ~[mariadb-java-client-2.6.1.jar:na]
jpa:
      database-platform: org.hibernate.dialect.MariaDBDialect
      hibernate:
        use-new-id-generator-mappings: false
        ddl-auto: create

    datasource:
      url: jdbc:mariadb://localhost:9005/waterloo
      username: waterloo
      password: xxx
      driver-class-name: org.mariadb.jdbc.Driver

when creating a application-prod.yml and moving all content from application.yml to application-prod.yml it tells me I have to configure a datasource URL

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is 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

I have the following questions:

  1. Do the application.yml files get layered (*-test.yml settings on top of application.yml)?
  2. Why does Spring try to build a connection to my database when I am not setting a datasource on my application-test.yml AND mocking the repository on the test?
  3. Is it normal that Spring trys to establish a connection at this part? 3.1) If not: How to i prevent it from doing so?

Thanks and kind regards!

R. Polito
  • 544
  • 6
  • 21

2 Answers2

3

Failed to determine a suitable driver class

You need to add mariadb driver dependency to your gradle or maven file.

https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client/2.6.2

Make sure that dependency scope is suitable for test

If you already have and its still not working try to clean and rebuild your project.

Your Questions:

Do the application.yml files get layered (*-test.yml settings on top of application.yml)?

If you add @ActiveProfiles("test") to you TestClass Spring will try to find an application-test.yml and overrrides application.yml properties with the given properties

Why does Spring try to build a connection to my database when I am not setting a datasource on my application-test.yml AND mocking the repository on the test?

Thats the magic of spring boot - it has default configurations for everything. You just need to set the Datasource properties and it will create the bean by itself.

Is it normal that Spring trys to establish a connection at this part? 3.1) If not: How to i prevent it from doing so?

You are starting the whole spring context with @SpringBootTest Annotation. So it will startup all Repositories and try to establish connection to your database. If you don't want spring to startup the database layer you can just use @WebMvcTest

eg:

@RunWith(SpringRunner.class)
@WebMvcTest
@ActiveProfiles("test")
public class StudentControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void contextLoads(){}

    //more tests
}

Check this out: https://spring.io/guides/gs/testing-web/

If you need to startup the whole SpringContext you can also disable Spring Data AutoConfiguration with:

@SpringBootApplication(exclude = {
    DataSourceAutoConfiguration.class, 
    DataSourceTransactionManagerAutoConfiguration.class, 
    HibernateJpaAutoConfiguration.class
})

Check this out: https://www.baeldung.com/spring-data-disable-auto-config

DCO
  • 1,222
  • 12
  • 24
  • here is the dependency: ```html org.mariadb.jdbc mariadb-java-client 2.6.1 ``` It shouln't establish the connection in testing in the first place, thats what i am trying to figure out :( – R. Polito Aug 10 '20 at 17:23
  • You are starting the whole spring context with SpringBootTest Annotation If you don't want spring to startup the database layer you can just use WebMvcTest Annotation Check this out: https://spring.io/guides/gs/testing-web/ – DCO Aug 10 '20 at 17:33
  • 1
    I cannot start it with WebMvcTest because I need Keycloak and security filter to work. The answers under my last stack overflow question I asked him they told me to use the @SpringBootTest :s – R. Polito Aug 10 '20 at 17:38
  • Ok - and why dont you want to establish a database connection? You could integrate a H2 imemory db in your test and just startup whole spring context – DCO Aug 10 '20 at 17:40
  • Did you tried to exclude Spring Data Autoconfiguration https://www.baeldung.com/spring-data-disable-auto-config – DCO Aug 10 '20 at 17:42
  • I added the H2 database to application-test.properties, and yet it tries to connect to the database, and find the database configuration – user2441441 Jun 07 '22 at 17:01
2

missed following annotation:

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
R. Polito
  • 544
  • 6
  • 21