Spring Boot DataJpaTest单元测试恢复为H2而不是mySql [英] Spring Boot DataJpaTest unit test reverting to H2 instead of mySql
问题描述
我有一个简单的小型"hello world" Spring Boot应用程序.它只有一个实体("IssueReport"),并且配置为运行mySQL(而不是默认的H2嵌入式数据库).
I've got a simple little "hello world" Spring Boot app. It has a single entity ("IssueReport") and it's configured to run mySQL (instead of the default H2 embedded database).
应用程序本身运行正常.我创建了一个mySql数据库和用户,Spring Boot/Hibernate创建了该表,并在运行该应用程序时成功填充并读取了mySQL数据.生活是美好的-mySQL和Spring Boot应用程序本身没有问题.
The app itself runs fine. I created a mySql database and user, Spring Boot/Hibernate created the table and successfully populates and reads the mySQL data when I run the app. Life is Good - there are no problems with mySQL and my Spring Boot app itself.
问:现在如何在单元测试中使用mySQL(而不是嵌入式H2)?
Q: Now how do I use mySQL (instead of the embedded H2) in unit tests?
-
我创建了另一个单独的mySQL数据库:
test2_test_db
.
我正在使用Spring Boot 2.0.6;STS 3.9.6上的Eclipse Photon;Ubuntu Linux.
I'm using Spring Boot 2.0.6; Eclipse Photon on STS 3.9.6; Ubuntu Linux.
我在 src/test/resources/
中创建了 application-test.properties
:
spring.datasource.url=jdbc:mysql://localhost:3306/test2_test_db
spring.datasource.username=springuser
spring.datasource.password=springuser
spring.jpa.hibernate.ddl-auto=create
这是整个单元测试:
Here's the entire unit test:
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...
}
}
这是控制台错误:
Here's the console error:
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应用一样?
Q: What's the EASIEST change so I can run my unit tests with mySQL, just as I'm able to run my Spring Boot app with mySQL?
问:"@ DataJpaTest"是这里的最佳选择,还是我应该尝试其他注释?
Q: Is "@DataJpaTest" the best choice here, or should I try a different annotation?
问:我必须创建一个单独的"Bean"类吗?如果是这样,您能举个例子吗?
Q: Must I create a separate "Bean" class? If so, can you point to an example?
=================================================================
================================================================
感谢您的所有答复.包括西蒙·马丁内利(Simon Martinelli)(现已删除)的回复.
Thank you for all your replies. Including Simon Martinelli's (now deleted) response.
解决方案:
-
我原来的
application-test.properties
可以正常使用.
我将其放置在错误的位置:任何配置文件的 all application.properties文件通常应放在同一项目文件夹中: src/主要/资源
I put it in the wrong place: all application.properties files for any profile should typically go in the same project folder: src/main/resources
< =示例: src/main/resources/application-test.properties
@Transactional
与此处无关-我将其删除.我将其保留为 @ActiveProfiles("test")
.
@Transactional
wasn't relevant here - I removed it. I kept it @ActiveProfiles("test")
.
根据Karthik R的建议,我添加了 @AutoConfigureTestDatabase(replace = Replace.NONE)
.
Per Karthik R's suggestion, I added @AutoConfigureTestDatabase(replace=Replace.NONE)
.
此时,测试成功读取了 application-test.properties
并使用MySQL代替了H2.
At that point, the test successfully read application-test.properties
and used MySQL instead of H2.
最终注释:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class IssueRepositoryIntegrationTests {
I found this link particularly helpful: Spring Boot – Profile based properties and yaml example
< =我一直在 http://www.mkyong.com 上找到所有资料.好!
<= I've always found all the material on http://www.mkyong.com extremely good!
推荐答案
默认情况下, @DataJpaTest
在内存H2数据库中用于回购测试.如果需要使用实际的数据库,则可以考虑禁用自动配置,也可以使用启用了整个应用程序Web MVC的 @SpringBootTest
.
By default, the @DataJpaTest
uses in memory H2 database for repo tests. Should you need to use the actual DB, you can consider either to disable the auto Configurations or use @SpringBootTest
where the whole application web mvc is enabled.
要禁用自动配置:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@Transactional
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class IssueRepositoryIntegrationTests
@AutoConfigureTestDatabase
为您配置测试H2 DB.您可以在上面特别提及不使用,也可以将此自动配置排除为:
@AutoConfigureTestDatabase
configures the test H2 DB for you. You can specifically mention not to by above or you can exclude this auto configuration as :
@EnableAutoConfiguration(exclude=AutoConfigureTestDatabase.class)
附言::我还没有尝试过上述排除方法.
P.S: : I have not tried the above exclusion myself yet.
有关更多信息,请访问javadoc: 查看全文