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).
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.
Q: Now how do I use mySQL (instead of the embedded H2) in unit tests?
I created a second, separate mySQL database:
test2_test_db.I'm using Spring Boot 2.0.6; Eclipse Photon on STS 3.9.6; Ubuntu Linux.
I created
application-test.propertiesinsrc/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=createHere'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...
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?
Q: Is "@DataJpaTest" the best choice here, or should I try a different annotation?
Q: Must I create a separate "Bean" class? If so, can you point to an example?
================================================================
Thank you for all your replies. Including Simon Martinelli's (now deleted) response.
RESOLUTION:
My original
application-test.propertieswas OK as-is.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<= EXAMPLE:
src/main/resources/application-test.properties@Transactionalwasn't relevant here - I removed it. I kept it@ActiveProfiles("test").Per Karthik R's suggestion, I added
@AutoConfigureTestDatabase(replace=Replace.NONE).At that point, the test successfully read
application-test.propertiesand used MySQL instead of H2.Final annotations:
@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
<= I've always found all the material on http://www.mkyong.com extremely good!