java - Spring Boot DataJpaTest 单元测试恢复到 H2 而不是 mySql
问题描述
我有一个简单的小“hello world”Spring Boot 应用程序。它有一个实体(“IssueReport”),并配置为运行 mySQL(而不是默认的 H2 嵌入式数据库)。
该应用程序本身运行良好。我创建了一个 mySql 数据库和用户,Spring Boot/Hibernate 创建了表,并在我运行应用程序时成功填充和读取了 mySQL 数据。生活是美好的 - mySQL 和我的 Spring Boot 应用程序本身没有问题。
问:现在如何在单元测试中使用 mySQL(而不是嵌入式 H2)?
我创建了第二个独立的 mySQL 数据库:
test2_test_db
.我正在使用 Spring Boot 2.0.6;STS 3.9.6 上的 Eclipse Photon;Ubuntu Linux。
我创建
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
这是整个单元测试:
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... } }
这是控制台错误:
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(现已删除)的回应。
解析度:
我的原件
application-test.properties
没问题。我把它放在错误的地方:任何配置文件的所有application.properties 文件通常应该放在同一个项目文件夹中:
src/main/resources
<= 示例:
src/main/resources/application-test.properties
@Transactional
在这里不相关 - 我删除了它。我保留了它@ActiveProfiles("test")
。根据 Karthik R 的建议,我添加了
@AutoConfigureTestDatabase(replace=Replace.NONE)
.至此,测试成功读取
application-test.properties
并使用了 MySQL 而不是 H2。最终注释:
@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上的所有材料都非常好!
解决方案
默认情况下,@DataJpaTest
使用内存 H2 数据库进行 repo 测试。如果您需要使用实际的数据库,您可以考虑禁用自动配置或使用@SpringBootTest
启用整个应用程序 web mvc 的位置。
要禁用自动配置:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@Transactional
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class IssueRepositoryIntegrationTests
@AutoConfigureTestDatabase
为您配置测试 H2 DB。您可以在上面特别提到不要,或者您可以将此自动配置排除为:
@EnableAutoConfiguration(exclude=AutoConfigureTestDatabase.class)
PS: : 我自己还没有尝试过上述排除。
有关通过 javadoc 的更多信息: https ://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/autoconfigure/jdbc/AutoConfigureTestDatabase.html
推荐阅读
- vb.net - 如何过滤通用对象列表
- python - 如何删除从文件中读取的字符串中的编码“b”?
- animation - Pygame是在不暂停程序的情况下减慢某个动画的帧速率的最佳方法?
- wpf - 如何修复 WPF MVVM 中的绑定 TextBlock?
- android - 有没有办法从我的 expo 应用程序 (react native 解决方案) 在“添加页面”上打开 instagram 应用程序?
- javascript - 如何遍历本地存储中的对象集合
- python-3.x - 如何使用cognitive_face调用Microsoft认知面部并将图像作为字节python传递
- assembly - 下面的汇编代码是做什么的?我需要编写一个代码来检查是否按下了 shift 按钮
- reactjs - 为什么 useReducer 第一个参数设置为调度值?
- node.js - 如何将包含图像Base64代码的字符串转换为字节?