Configuration de sources de données de ressort distinctes pour les tests

Configuration de sources de données de ressort distinctes pour les tests

1. Vue d'ensemble

Lors du test d'une application Spring reposant sur une couche de persistance, telle que JPA, il peut être utile de configurer une source de données de test pour utiliser une base de données plus petite et plus rapide, différente de celle utilisée pour exécuter l'application, afin: pour rendre nos tests beaucoup plus faciles.

La configuration d'une source de données dans Spring nécessite la définition d'un bean de typeDataSource, soit manuellement, soit, si vous utilisez Spring Boot, via les propriétés d'application standard.

Dans ce rapide tutoriel, nous allons jeter un œil àseveral ways to configure a separate data source for testing in Spring.

2. Dépendances Maven

Nous allons créer une application Spring Boot à l'aide de Spring JPA et de tests. Nous aurons donc besoin des dépendances suivantes:


    org.springframework.boot
    spring-boot-starter-data-jpa
    2.1.3.RELEASE


    com.h2database
    h2
    1.4.197


    org.springframework.boot
    spring-boot-starter-test
    2.1.3.RELEASE

Les dernières versions despring-boot-starter-data-jpa,h2 etspring-boot-starter-test peuvent être téléchargées depuis Maven Central.

Jetons un coup d'œil à différentes façons de configurer unDataSource pour le test.

3. Utilisation d'un fichier de propriétés standard dans Spring Boot

Le fichier de propriétés standard que Spring Boot récupère automatiquement lors de l'exécution d'une application est appeléapplication.properties et réside dans le dossiersrc/main/resources.

Si nous voulons utiliser des propriétés différentes pour les tests, nous pouvons remplacer le fichier de propriétés dans le dossiermain en plaçant un autre fichier avec le même nom danssrc/test/resources.

Le fichierapplication.properties du dossiersrc/test/resources doit contenir les paires clé-valeur standard nécessaires à la configuration d'une source de données. Ces propriétés sont précédées despring.datasource.

Par exemple, configurons une base de données en mémoireH2 comme source de données pour les tests:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

Spring Boot utilisera ces propriétés pour configurer automatiquement un beanDataSource.

Définissons unGenericEntity très simple et un référentiel à l'aide de Spring JPA:

@Entity
public class GenericEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String value;

    //standard constructors, getters, setters
}
public interface GenericEntityRepository
  extends JpaRepository { }

Ensuite, écrivons un testJUnit pour le référentiel. Pour qu'un test dans une application Spring Boot récupère les propriétés de source de données standard que nous avons définies, il doit être annoté avec@SpringBootTest:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class SpringBootJPAIntegrationTest {

    @Autowired
    private GenericEntityRepository genericEntityRepository;

    @Test
    public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
        GenericEntity genericEntity = genericEntityRepository
          .save(new GenericEntity("test"));
        GenericEntity foundEntity = genericEntityRepository
          .findOne(genericEntity.getId());

        assertNotNull(foundEntity);
        assertEquals(genericEntity.getValue(), foundEntity.getValue());
    }
}

4. Utilisation d'un fichier de propriétés personnalisées

Si nous ne voulons pas utiliser le fichier et les clés standardapplication.properties, ou si nous n'utilisons pas Spring Boot, nous pouvons définir un fichier.properties personnalisé avec des clés personnalisées, puis lire ce fichier dans un Classe@Configuration pour créer un beanDataSource basé sur les valeurs qu'il contient.

Ce fichier sera placé dans le dossiersrc/main/resources pour le mode de fonctionnement normal de l'application, et danssrc/test/resources afin d'être récupéré par les tests.

Créons un fichier appelépersistence-generic-entity.properties qui utilise une base de données en mémoireH2 pour les tests et placez-le dans le dossiersrc/test/resources:

jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.username=sa
jdbc.password=sa

Ensuite, nous pouvons définir le beanDataSource en fonction de ces propriétés dans une classe@Configuration qui charge nospersistence-generic-entity.properties comme source de propriété:

@Configuration
@EnableJpaRepositories(basePackages = "org.example.repository")
@PropertySource("persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
    // ...
}

Pour un exemple plus détaillé de cette configuration, veuillez consulter notre article précédent surSelf-contained testing with an in-memory database, section «Configuration JPA».

Ensuite, nous pouvons créer un testJUnit similaire au précédent, sauf qu'il chargera notre classe de configuration:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, H2JpaConfig.class})
public class SpringBootH2IntegrationTest {
    // ...
}

5. Utilisation des profils de ressort

Une autre façon de configurer unDataSource distinct pour les tests consiste à utiliser Spring Profiles pour définir un beanDataSource qui n'est disponible que dans un profiltest.

Pour cela, nous pouvons utiliser un fichier.properties comme auparavant, ou nous pouvons écrire les valeurs dans la classe elle-même.

Définissons un beanDataSource pour le profiltest dans une classe@Configuration qui sera chargée par notre test:

@Configuration
@EnableJpaRepositories(basePackages = {
  "org.example.repository",
  "org.example.boot.repository"
})
@EnableTransactionManagement
public class H2TestProfileJPAConfig {

    @Bean
    @Profile("test")
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:db;DB_CLOSE_DELAY=-1");
        dataSource.setUsername("sa");
        dataSource.setPassword("sa");

        return dataSource;
    }

    // configure entityManagerFactory
    // configure transactionManager
    // configure additional Hibernate properties
}

Ensuite, dans la classe de testJUnit, nous devons spécifier que nous voulons utiliser le profiltest en ajoutant l'annotation@ActiveProfiles:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
  Application.class,
  H2TestProfileJPAConfig.class})
@ActiveProfiles("test")
public class SpringBootProfileIntegrationTest {
    // ...
}

6. Conclusion

Dans ce rapide tutoriel, nous avons vu plusieurs façons de configurer unDataSource distinct pour le test au printemps.

Comme toujours, le code source complet des exemples peut être trouvéover on GitHub.