代码之家  ›  专栏  ›  技术社区  ›  paulsm4

Spring Boot DataJpaTest单元测试恢复为H2而不是mySql

  •  2
  • paulsm4  · 技术社区  · 7 年前

    我有一个简单的小“你好世界”春季启动应用程序。它只有一个实体(“IssueReport”),并配置为运行mySQL(而不是默认的H2嵌入式数据库)。

    问:现在我如何在单元测试中使用mySQL(而不是嵌入式H2)?

    1. 我创建了第二个单独的mySQL数据库: test2_test_db .

    2. 我使用的是springboot2.0.6;sts3.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运行我的单元测试,就像我可以用mySQL运行我的Spring Boot应用一样?

    问:“@DataJpaTest”是这里的最佳选择,还是我应该尝试不同的注释?

    问:我必须创建一个单独的“Bean”类吗?如果是,你能举个例子吗?

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

    谢谢你的回复。包括Simon Martinelli(现已删除)的回复。

    1. 我的原件 应用测试属性 一切正常。

    2. 我放错地方了: 的application.properties文件 任何 src/main/resources

      <=示例: src/main/resources/application-test.properties

    3. @Transactional 与此无关-我删除了它。我留着它 @ActiveProfiles("test")

    4. 根据卡尔蒂克的建议,我补充道 @AutoConfigureTestDatabase(replace=Replace.NONE)

    5. 应用测试属性 用MySQL代替H2。

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

    我发现这个链接特别有用: Spring Boot – Profile based properties and yaml example

    <我总是能找到所有的材料 http://www.mkyong.com 非常好!

    2 回复  |  直到 7 年前
        1
  •  18
  •   Karthik R    7 年前

    默认情况下 @DataJpaTest 使用内存中的H2数据库进行repo测试。如果需要使用实际的DB,可以考虑禁用自动配置或使用。 @SpringBootTest 其中启用了整个应用程序webmvc。

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

    @AutoConfigureTestDatabase 为您配置测试数据库。您可以在上面特别提到,也可以排除此自动配置:

    @EnableAutoConfiguration(exclude=AutoConfigureTestDatabase.class)
    

    附笔: :我自己还没有尝试过上述排除。

    欲了解更多信息,请通过javadoc: https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabase.html

        2
  •  2
  •   Kamil W    7 年前

    @DataJpaTest documentation

    默认情况下,用@DataJpaTest注释的测试将使用嵌入的 内存数据库(替换任何显式或通常自动配置的 数据源)。

    @Transactional 注释在测试上下文中的行为方式与在应用程序上下文中的不同:

    从春天开始 documentation :

    在默认情况下自动回滚的事务中 测试完成后。

    Configuring Separate Spring DataSource for Tests
    Testing with @Configuration Classes and Profiles