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]?
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")
.
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...
}
}
@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).
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.
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 :)
Avec la magie @SpringBootTest, il vous suffit de faire les deux modifications suivantes.
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency>
@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.