web-dev-qa-db-fra.com

Configurer une base de données spécifique en mémoire à des fins de test dans Spring

Comment configurer mon application Spring Boot de telle sorte que lorsque j'exécute des tests unitaires, elle utilise une base de données en mémoire telle que H2/HSQL mais que, lorsque j'exécute l'application Spring Boot, elle utilise une base de données de production [Postgre/MySQL]?

38
IllSc

Les profils de ressort peuvent être utilisés pour cela. Ce serait une manière spécifique:

Avoir des fichiers de propriétés spécifiques à l'environnement:

application.properties:

spring.profiles.active: dev

application-dev.properties

spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: update

spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password

application-test.properties

spring.jpa.database: HSQL

Avoir les deux pilotes MySQL et H2 dans pom.xml, comme ça:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-Java</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>test</scope>
</dependency>

Dernier point mais non le moindre, annotez les classes de test avec @ActiveProfiles("test").

51
Sanjay

Une autre approche consiste à ajouter l'annotation @AutoConfigureTestDatabase à votre classe de test. Mes tests ressemblent généralement à ceci:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class MyRepositoryTest {

    @Autowired
    MyRepository repository;

    @Test
    public void test() throws Exception {
        // Tests...
    }
}
28
ronhash

@Sanjay a une façon de le dire mais je trouve cela déroutant. Vous pourriez aussi bien n'avoir qu'un profil production que vous activez lorsque vous êtes en production, quelque chose comme:

spring.jpa.hibernate.ddl-auto: update
spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password

Et ne spécifiez rien d'autre. Si vous ajoutez une base de données intégrée dans test scope, elle sera disponible dans vos tests. Si vous exécutez vos tests avec le profil par défaut (aucune personnalisation), il ne trouvera aucune information sur la base de données (car celles-ci sont stockées dans le profil production.). Dans ce cas, il essaiera de trouver une base de données intégrée et de la démarrer pour vous. Si vous avez besoin de plus de personnalisation pour une raison quelconque, vous pouvez avoir un application-test.properties Pour ceux-là (vous aurez besoin d'ajouter ActiveProfiles("test")) à votre (vos) test (s).

6
Stephane Nicoll

La solution la plus simple:

1) dans src/main/resources ont application.properties (configuration de production):

spring.datasource.url=jdbc:mysql://localhost:3306/somedb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect

et application-test.properties avec la configuration HSQL comme:

spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.database = HSQL
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.HSQLDialect
spring.datasource.driverClassName = org.hsqldb.jdbcDriver
spring.datasource.url= jdbc:hsqldb:mem:scratchdb
spring.datasource.username = sa
spring.datasource.password =

2) Ajoutez la dépendance HSQL dans pom.xml si vous ne l’avez pas déjà.

3) Annotez votre classe de test avec @ActiveProfiles ("test").

Travaillé comme un charme dans mon cas.

5
jarosik

Solution simple si vous construisez avec maven: placez simplement un fichier application.properties Sous src/test/resources Et modifiez-le comme il convient pour les tests.

Le mécanisme Spring (Boot) Profile est un outil assez puissant qui va bien au-delà de la "permutation des paramètres entre le temps de test et le temps d’exécution". Bien que, clairement, comme démontré, il peut faire cela aussi :)

5
demaniak

Avec la magie @SpringBootTest, il vous suffit de faire les deux modifications suivantes.

  1. Ajouter la dépendance de test 'h2' dans pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>
  1. Utilisez @ AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
@AutoConfigureTestDatabase
public class SpringBootTest{

    @Autowired
    private RequestRepository requestRepository;
}

Désormais, tous les référentiels de beans jpa de printemps utilisés dans le test utiliseront h2 comme base de données de sauvegarde.

2019-04-26 13: 13: 34.198 INFO 28627 --- [main] beddedDataSourceBeanFactoryPostProcessor: Remplacement du bean DataSource avec la version intégrée

2019-04-26 13: 13: 34.199 INFO 28627 --- [main] o.s.b.f.s.DefaultListableBeanFactory: Remplacement de la définition du bean pour le bean 'dataSource'

2019-04-26 13: 13: 36.194 INFO 28627 --- [main] osjdeEmbeddedDatabaseFactory: démarrage de la base de données intégrée: url = 'jdbc: h2: mem: 2784768e-f053-4bb3-ab88-edda34956893; DB_CLOSE_DELAY = -1; DB_CLOSE_ON_EXEND = false ', nom d'utilisateur =' sa '

Remarque: j'ai toujours les propriétés 'spring-jpa' définies dans 'application.properties' et je n'utilise aucun profil. @ AutoConfigureTestDatabase annulera les configurations jpa existantes avec les valeurs par défaut du test AutoConfigureTestDatabase.Replace.

1
147.3k