Тесты JUnit 5 для подпроекта без приложения SpringBootApplication

#java #spring-boot #gradle #spring-data-jpa #junit-jupiter

#java #весенняя загрузка #gradle #spring-data-jpa #junit-jupiter

Вопрос:

В частности, у меня есть подпроект, который принадлежит сборке с несколькими проектами.
У подпроекта нет SpringBootApplication своего собственного.
После некоторых исследований я обнаружил, что в ClassPath @SpringBootConfiguration выполняется поиск
, но теперь я не могу продвинуться дальше, потому DataSource что то, что настроено в application.yml , не найдено.

Выдается следующее исключение:

 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'de.acme.storage.DBConnectionTest': Unsatisfied dependency expressed through field 'dataSource'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    ...
  

Я ожидал увидеть результат: DataSource: HikariDataSource (HikariPool-1) как описано в руководстве о Spring Boot 2 и Hikari.
Однако это руководство было удовлетворено «тестом» в классе SpringBootApplication.

В чем моя вина?

Структура подпроекта выглядит следующим образом:

 src
 ---main
|   ---java
|   |   ---de
|   |       ---acme
|   |           ---storage
|   |                ---model
|   |               |       User.java
|   |               |       
|   |               ---mysql
|   |                       UserDAOImpl.java
|               
---test
     ---java
    |   ---de
    |       ---acme
    |           ---storage
    |                   DBConnectionTest.java
    |                   TestConfig.java
    |                   
    ---resources
            application.yml
  

Build.gradle подпроекта:

 plugins {
    id 'org.springframework.boot'
}

apply plugin: 'io.spring.dependency-management'

dependencies {
    implementation project(':api'),
            'javax.inject:javax.inject:1',
            'org.springframework.boot:spring-boot-starter-data-jpa'

    runtime 'mysql:mysql-connector-java'
}
  

Build.gradle в основном проекте содержит этот раздел зависимостей:

 dependencies {
    implementation 'org.slf4j:slf4j-api'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'junit', module: 'junit' //by both name and group
    }
    testImplementation 'org.junit.jupiter:junit-jupiter-api',
            'org.junit.jupiter:junit-jupiter-params'

    testRuntime 'org.junit.jupiter:junit-jupiter-engine'
}
  

Приложение.содержимое yml:

 spring:
  datasource:
    url: jdbc:mysql://localhost:13306/testdb
    username: test-user
    password: geheim
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect
        format_sql: true
        id:
          new_generator_mappings: false
  

Тест JUnit:

 @SpringBootTest
class DBConnectionTest {
    private static final Logger LOG = LoggerFactory.getLogger(DBConnectionTest.class);

    @Inject
    private DataSource dataSource;

    @Test
    void test() {
        LOG.debug("DataSource: {}", dataSource);
        assertThat(dataSource).as("Es gibt eine Datasource").isNotNull();
    }
}
  

И, наконец, пустая конфигурация с @SpringBootConfiguration аннотацией:

 package de.acme.storage;

import org.springframework.boot.SpringBootConfiguration;

@SpringBootConfiguration
class TestConfig {
}
  

Ответ №1:

Не хватало только одной мелочи — аннотации @EnableAutoConfiguration . Думал, что это будет сделано @SpringBootConfiguration

 package de.acme.storage;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

@SpringBootConfiguration
@EnableAutoConfiguration
class TestConfig {
}