Модульный тест spring boot datajpatest возвращается к h2 вместо mysql

У меня есть простое маленькое приложение Spring Boot "привет мир". Он имеет одну сущность («IssueReport») и настроен для запуска mySQL (вместо встроенной базы данных H2 по умолчанию).

Само приложение работает нормально. Я создал базу данных mySql и пользователя, Spring Boot / Hibernate создал таблицу и успешно заполняет и считывает данные mySQL при запуске приложения. Life is Good - нет никаких проблем с mySQL и моим приложением Spring Boot.

В: Как теперь использовать mySQL (вместо встроенного H2) в модульных тестах?

  1. Я создал вторую отдельную базу данных mySQL: test2_test_db.

  2. Я использую Spring Boot 2.0.6; Eclipse Photon на STS 3.9.6; Ubuntu Linux.

  3. Я создал application-test.properties в src/test/resources/:

    spring.datasource.url=jdbc:mysql://localhost:3306/test2_test_db
    spring.datasource.username=springuser
    spring.datasource.password=springuser
    spring.jpa.hibernate.ddl-auto=create
    
  4. Вот весь модульный тест:

    package com.hellospring.example;
    
    import static org.assertj.core.api.Assertions.assertThat;
    import java.util.List;
    import javax.transaction.Transactional;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
    import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
    import org.springframework.test.context.ActiveProfiles;
    import org.springframework.test.context.junit4.SpringRunner;
    import com.hellospring.example.entity.IssueReport;
    import com.hellospring.example.repositories.IssueRepository;
    
    @RunWith(SpringRunner.class)
    @ActiveProfiles("test")
    @Transactional
    @DataJpaTest
    public class IssueRepositoryIntegrationTests {
    
         @Autowired
         private TestEntityManager entityManager;
    
         @Autowired
         private IssueRepository issueRepository;
    
         @Test
         public void addNewIssue() {
             System.out.println("addNewIssue()...");  // <-- This prints in the console
             final String email = "test@test.io";
             List<IssueReport> resultSet = issueRepository.findAll();  // <-- We get an exception in here...
         }  
    }
    
  5. Вот ошибка консоли:

    2018-10-25 22:20:16.381  INFO 13637 --- [           main] c.v.e.IssueRepositoryIntegrationTests    : The following profiles are active: test
    2018-10-25 22:20:16.405  INFO 13637 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@d554c5f: startup date [Thu Oct 25 22:20:16 PDT 2018]; root of context hierarchy
    2018-10-25 22:20:17.059  INFO 13637 --- [           main] beddedDataSourceBeanFactoryPostProcessor : Replacing 'dataSource' DataSource bean with embedded version
    2018-10-25 22:20:17.060  INFO 13637 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] with [Root bean: class [org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
    2018-10-25 22:20:17.308  INFO 13637 --- [           main] o.s.j.d.e.EmbeddedDatabaseFactory        : Starting embedded database: url='jdbc:h2:mem:979b3ce9-604e-4efd-a6d4-79576c3d67e9;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
    2018-10-25 22:20:17.685  INFO 13637 --- [           main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
      ...  <= I do *NOT* want H2!  I want mySQL!
    
    2018-10-25 22:20:19.315  WARN 13637 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 42102, SQLState: 42S02
    2018-10-25 22:20:19.316 ERROR 13637 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Table "ISSUE_REPORT" not found; SQL statement:
      ...  <= Here's the exception from running the test...
    

В: Какое изменение ПРОСТОЕ, чтобы я мог запускать свои модульные тесты с помощью mySQL, так же как я могу запускать приложение Spring Boot с помощью mySQL?

В: "@DataJpaTest" - лучший выбор здесь, или мне стоит попробовать другую аннотацию?

В: Должен ли я создать отдельный класс «Бин»? Если да, то не могли бы вы привести пример?

================================================== ==============

Спасибо вам за все ваши ответы. Включая ответ Саймона Мартинелли (теперь удален).

РАЗРЕШАЮЩАЯ СПОСОБНОСТЬ:

  1. Мой оригинальный application-test.properties был в порядке как есть.

  2. Я поместил его не в то место: файлы все application.properties для профиля любой обычно должны находиться в той же папке проекта: src/main/resources

    <= ПРИМЕР: src/main/resources/application-test.properties

  3. @Transactional здесь не актуален - я его удалил. Я сохранил его @ActiveProfiles("test").

  4. По предложению Картика Р. я добавил @AutoConfigureTestDatabase(replace=Replace.NONE).

  5. В этот момент тест успешно прочитал application-test.properties и использовал MySQL вместо H2.

  6. Заключительные аннотации:

    @RunWith(SpringRunner.class)
    @ActiveProfiles("test")
    @DataJpaTest
    @AutoConfigureTestDatabase(replace=Replace.NONE)
    public class IssueRepositoryIntegrationTests {
    

Я нашел эту ссылку особенно полезной: Spring Boot - свойства на основе профиля и пример yaml

<= Я всегда находил все материалы по http://www.mkyong.com очень хорошими!

10
0
13 810
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Из @DataJpaTestдокументация:

By default, tests annotated with @DataJpaTest will use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource).

Если вы обратитесь к документации, вы увидите, что эта аннотация объединяет множество других аннотаций.

Аннотация @Transactional ведет себя иначе в контексте теста, чем в контексте приложения:

С пружины документация:

Annotating a test method with @Transactional causes the test to be run within a transaction that is, by default, automatically rolled back after completion of the test.

Я считаю, что предоставил достаточно информации, отвечая на ваш вопрос, кроме того, вы можете ознакомиться со следующими статьями:

Настройка отдельного источника данных Spring для тестов
Тестирование с использованием классов и профилей @Configuration

Ответ принят как подходящий

По умолчанию @DataJpaTest использует в памяти базу данных H2 для тестов репо. Если вам нужно использовать фактическую базу данных, вы можете рассмотреть возможность отключения автоматических конфигураций или использования @SpringBootTest, где включен весь веб-mvc приложения.

Чтобы отключить автоконфигурацию:

@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@Transactional
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class IssueRepositoryIntegrationTests 

@AutoConfigureTestDatabase настраивает для вас тестовую базу данных H2. Вы можете специально упомянуть, что не следует выше, или вы можете исключить эту автоконфигурацию как:

@EnableAutoConfiguration(exclude=AutoConfigureTestDatabase.class)

P.S:: Я сам еще не пробовал это исключение.

Для получения дополнительной информации об этом перейдите в javadoc:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabase.html

У меня проблема только с расшифровкой, я использую @DataJpaTest, а пароль зашифрован с помощью jasypt, он не может подключиться к db, используя jasypt для тестирования

Tiago Medici 06.09.2019 15:53

не могли бы вы описать, как вы шифруете свой пароль? Я использую jasypt, а с datajpatest он не работает, игнорирует шифрование ...

Tiago Medici 06.09.2019 16:19

Спасибо, это было очень полезно. Я не понимал, почему мои интеграционные тесты после учебника: baeldung.com/spring-testing-separate-data-source смогли использовать источник данных, который я выбрал с помощью аннотации PropertySource, но мои обычные тесты, в которых аннотация DataJpaTest была дополнена нежелательной БД. С помощью этого AutoCOnfigureTestDatabse я являюсь приложением для фактического использования, например, application-postgres.properties. Это хорошо.

99Sono 20.10.2019 13:24
@AutoConfigureTestDatabase(replace=Replace.NONE) работает на меня и спас мне день. Целый день я отлаживал каждый уголок и искал огромное количество ресурсов, но не нашел причины для включения автоматически настроенной базы данных. Это отличное решение.
sunkuet02 23.10.2020 11:24

Другие вопросы по теме