R. Polito
R. Polito

Reputation: 544

Spring Test Wants To Connect to Database

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!

Upvotes: 6

Views: 9789

Answers (2)

R. Polito
R. Polito

Reputation: 544

missed following annotation:

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

Upvotes: 2

DCO
DCO

Reputation: 1292

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

Upvotes: 4

Related Questions