@Autowired и UnsatisfiedDependencyException в интеграционном тесте Spring - PullRequest
0 голосов
/ 11 марта 2020

У меня есть многомодульный проект с загрузкой Spring и внешним сервером. Weblogi c.

Это модули:

  • dao
  • service
  • web

    pom. xml (dao).

Работа с базой данных (хранилище, сущности)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gov-multiple-modules</artifactId>
        <groupId>gov</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>


    <groupId>com.dao</groupId>
    <artifactId>dao</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <output.directory.jdbc.oracle>${project.basedir}/src/main/resources</output.directory.jdbc.oracle>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc</artifactId>
            <version>6</version>
            <scope>system</scope>
            <systemPath>${output.directory.jdbc.oracle}/lib/ojdbc6.jar</systemPath>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <argLine>-Dfile.encoding=UTF8</argLine>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

  • пом. xml (служба)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gov-multiple-modules</artifactId>
        <groupId>gov</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.service</groupId>
    <artifactId>service</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.dao</groupId>
            <artifactId>dao</artifactId>
            <version>${version.dao.module}</version>
        </dependency>


        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${version.mapstruct}</version>
        </dependency>

    </dependencies>


    <build>
          <plugins>

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-surefire-plugin</artifactId>
                  <configuration>
                      <argLine>-Dfile.encoding=UTF8</argLine>
                  </configuration>
              </plugin>

            <plugin> 
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${version.apache.maven.plugins}</version>
                <groupId>org.apache.maven.plugins</groupId>

                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${version.mapstruct}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

  • pom. xml (web)

    Это работа с запросами от клиентов (Contoroller и RestControllers).

В приложении есть точка входа.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>gov-multiple-modules</artifactId>
        <groupId>gov</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.web</groupId>
    <artifactId>web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.service</groupId>
            <artifactId>service</artifactId>
            <version>${version.service.module}</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>weblogic-war-gov</finalName>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <argLine>-Dfile.encoding=UTF8</argLine>
                </configuration>
            </plugin>


            <plugin> <!--It is for convert beans-->
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${version.apache.maven.plugins}</version>
                <groupId>org.apache.maven.plugins</groupId>

                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${version.mapstruct}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

  • pom. xml (parrent)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <modules>
        <module>dao</module>
        <module>service</module>
        <module>web</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>gov</groupId>
    <artifactId>gov-multiple-modules</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>gov-multiple-modules</name>
    <description>project with Spring Boot for multiple module applications</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <version.apache.maven.plugins>3.8.1</version.apache.maven.plugins>
        <version.mapstruct>1.3.0.Final</version.mapstruct>

        <version.apache.common.lang3>3.9</version.apache.common.lang3>
        <version.apache.commons.text>1.8</version.apache.commons.text>
        <version.apache.commons.beanutils>1.9.4</version.apache.commons.beanutils>
        <version.hibernate.validator>6.0.17.Final</version.hibernate.validator>
        <version.reflection>0.9.11</version.reflection>
        <version.dao.module>0.0.1-SNAPSHOT</version.dao.module>
        <version.service.module>0.0.1-SNAPSHOT</version.service.module>

    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--This artifact need for testing that to find classes into classpath-->
        <dependency>
            <groupId>org.reflections</groupId>
            <artifactId>reflections</artifactId>
            <version>${version.reflection}</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${version.apache.common.lang3}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>${version.apache.commons.text}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>${version.apache.commons.beanutils}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

    </dependencies>

</project>

В веб-модуль входит test-dir.

  • src / test / java / com / web

Вот хранилище

  • src / test / java / com / web / dao / repository / company / CompanyReadRepositoryTest. java
public interface CompanyReadRepositoryTest extends CrudRepository<Company, Long> {

    String nameTable = "company";
    String lastEntryQueryFor =
            "select * from (select t.* from " + nameTable + " t order by 1 desc) where rownum = 1";

    @Query(value =lastEntryQueryFor, nativeQuery = true)
    Optional<Company> getLastEntry();
}

У меня есть класс для тестов.

@RunWith(SpringRunner.class)
@SpringBootTest
@Sql({
        "classpath:sql/create_sequence_different_types.sql",
        "classpath:sql/create-company.sql",
        "classpath:sql/insert_company.sql"
})
public class CompanyReadServiceTest {


    private static final Logger LOGGER = LoggerFactory.getLogger(CompanyReadServiceTest.class);

    private static String NAME_METHOD_READ_BY_NAME_BOOLEAN = "isByName";


    @Autowired
    private CompanyReadService companyReadService;

    @Autowired
    private CompanyReadRepositoryTest companyReadRepositoryTest;


    @Test
    public void getById() {
...

во время запуска класса, компонент CompanyReadRepositoryTest не присоединится.

java .lang.IllegalStateException: не удалось загрузить ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)

...

Вызывается: org.springframework.beans.factory.UnsatisfiedDependencyException: Ошибка при создании bean-компонента с именем «companyReadServiceTest»: неудовлетворенная зависимость, выраженная через поле «companyReadService»; вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: нет доступного квалифицирующего компонента типа com.service.read.company.CompanyReadService: ожидается как минимум 1 компонент, который считается кандидатом на автопровод. Аннотации зависимостей: {@ org.springframework.beans.factory.annotation.Autowired (обязательно = true)} в org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject

1074 1072 1072 Добавлено

Я немного делаю

@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebSpringBootJarApplication.class )
@AutoConfigureTestDatabase(replace = NONE)
@Sql({
        "classpath:sql/create_sequence_different_types.sql",
        "classpath:sql/create-company.sql",
        "classpath:sql/insert_company.sql"
})
@TestPropertySource(
        locations = "classpath:application-integration-test.properties")
public class CompanyReadServiceTest {


    private static final Logger LOGGER = LoggerFactory.getLogger(CompanyReadServiceTest.class);

    private static String NAME_METHOD_READ_BY_NAME_BOOLEAN = "isByName";

    @Autowired
    private CompanyReadService companyReadService;

    @Autowired
    private CompanyReadRepositoryTest companyReadRepositoryTest;


    @Test
    public void getById() {

...

сейчас ...

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.web.service.read.company.CompanyReadServiceTest': Unsatisfied dependency expressed through field 'companyReadRepositoryTest'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.web.dao.repository.company.CompanyReadRepositoryTest' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Есть идеи, что это за ошибки? Пожалуйста.

Ответы [ 2 ]

0 голосов
/ 11 марта 2020

Решение

Вам необходимо переместить dao.repository в root test-dir. Этот каталог com.

src / test / java / com / dao / repository

Вы повторяете расположение репозиториев в dao-модуле.

@RunWith(SpringRunner.class)
@SpringBootTest
@Sql({
        "classpath:sql/create_sequence_different_types.sql",
        "classpath:sql/create-company.sql",
        "classpath:sql/insert_company.sql"
})
@TestPropertySource(
        locations = "classpath:application-integration-test.properties")
public class CompanyReadServiceTest {
...
0 голосов
/ 11 марта 2020

В вашем случае CompanyReadRepositoryTest не аннотируется какой-либо аннотацией определения компонента (например, @Component и теми, которые его расширяют). Spring не распознает ни один bean-компонент нужного типа и не может внедрить его в ваше свойство.

Как вы можете видеть, существует исключение NoSuchBeanDefinitionException, говорящее о том, что нет ни одного bean-компонента, который квалифицируется как кандидат для автоматической передачи.

Просто аннотируйте свой CompanyReadRepositoryTest с помощью @Component (или любой аннотации определения компонента), и все будет хорошо.

В вашем случае лучшей аннотацией является @ Repository.

Посмотрите, в чем разница между @Repository и другими аннотациями определения бина.

...