Test autonome en utilisant une base de données en mémoire
1. Vue d'ensemble
Dans ce didacticiel, nous allons àcreate a simple Spring application which relies on an in-memory database for testing.
Pour le profil standard, l'application disposera d'une configuration de base de données MySQL autonome, qui nécessite l'installation et le fonctionnement du serveur MySQL, avec un utilisateur et une base de données appropriés.
Pour faciliter le test de l'application, nous renoncerons à la configuration supplémentaire requise par MySQL et utiliserons à la place une base de données en mémoireH2 pour exécuter les tests JUnit.
2. Dépendances Maven
Pour le développement, nous avons besoin des dépendances suivantes:
org.springframework
spring-test
4.3.7.RELEASE
org.springframework.data
spring-data-jpa
1.11.1.RELEASE
com.h2database
h2
1.4.194
org.hibernate
hibernate-entitymanager
5.2.9.Final
Les dernières versions despring-test,spring-data-jpa,h2 ethibernate-entitymanager peuvent être téléchargées depuis Maven Central.
3. Modèle de données et référentiel
Créons une simple classeStudent qui sera marquée comme une entité:
@Entity
public class Student {
@Id
private long id;
private String name;
// standard constructor, getters, setters
}
Ensuite, créons une interface de référentiel basée sur Spring Data JPA:
public interface StudentRepository extends JpaRepository {
}
Cela permettra à Spring de créer le support pour la manipulation des objetsStudent.
4. Sources de propriété distinctes
Pour permettre l'utilisation de différentes configurations de base de données pour le mode standard et le mode test, nous pouvons lire les propriétés de la base de données à partir d'un fichier dont l'emplacement est différent selon le mode d'exécution de l'application.
For normal mode, the properties file will reside in src/main/resources, and for the testing method, we will use a properties file in the src/test/resources folder.
Lors de l'exécution d'un test, l'application recherchera d'abord les fichiers dans le dossiersrc/test/resources. Si le fichier n'est pas trouvé à cet emplacement, il utilisera celui défini dans le dossiersrc/main/resources. Si le fichier est présent dans le chemin detest, alors il remplacera celui du chemin demain.
4.1. Définition des fichiers de propriétés
Créons un fichierpersistence-student.properties dans le dossiersrc/main/resources qui définit les propriétés d’une source de données MySQL:
dbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/myDb
jdbc.user=tutorialuser
jdbc.pass=tutorialpass
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.hbm2ddl.auto=create-drop
Dans le cas de la configuration ci-dessus, nous aurons besoin d'avoir la base de donnéesmyDb créée et l'utilisateur detutorialuser/tutorialpass configuré.
Puisque nous voulons utiliser une base de données en mémoire pour les tests, nous allons créer un fichier similaire avec le même nom dans le dossiersrc/test/resources, contenant les propriétés avec les mêmes clés et les valeurs spécifiques à la base de donnéesH2:
jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create
Nous avons configuré la base de donnéesH2 pour qu'elle vive en mémoire et qu'elle soit créée automatiquement, puis fermée et supprimée lorsque la JVM se termine.
4.2. Configuration JPA
Créons une classe@Configuration qui recherche un fichier appelépersistence-student.properties comme source de propriété et crée unDataSource à l’aide des propriétés de base de données qui y sont définies:
@Configuration
@EnableJpaRepositories(basePackages = "org.example.persistence.dao")
@PropertySource("persistence-student.properties")
@EnableTransactionManagement
public class StudentJpaConfig {
@Autowired
private Environment env;
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
dataSource.setUrl(env.getProperty("jdbc.url"));
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.pass"));
return dataSource;
}
// configure entityManagerFactory
// configure transactionManager
// configure additional Hibernate Properties
}
5. Création d'un test JUnit
Écrivons un test JUnit simple basé sur la configuration décrite ci-dessus qui utilise lesStudentRepository pour enregistrer et récupérer une entitéStudent:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
classes = { StudentJpaConfig.class },
loader = AnnotationConfigContextLoader.class)
@Transactional
public class InMemoryDBTest {
@Resource
private StudentRepository studentRepository;
@Test
public void givenStudent_whenSave_thenGetOk() {
Student student = new Student(1, "john");
studentRepository.save(student);
Student student2 = studentRepository.findOne(1);
assertEquals("john", student2.getName());
}
}
Our test will run in an entirely self-contained manner - il créera une base de donnéesH2 en mémoire, exécutera des instructions, puis fermera la connexion et supprimera la base de données, comme nous pouvons le voir dans le journal:
INFO: HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate: drop table Student if exists
Hibernate: create table Student (id bigint not null, name varchar(255), primary key (id))
Mar 24, 2017 12:41:51 PM org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources
INFO: HHH000476: Executing import script 'org.hiber[email protected]1b8f9e2'
Hibernate: select student0_.id as id1_0_0_, student0_.name as name2_0_0_ from Student student0_ where student0_.id=?
Hibernate: drop table Student if exists
6. Conclusion
Dans cet exemple rapide, nous avons montré comment nous pouvons exécuter un test autonome à l'aide d'une base de données en mémoire.
Comme toujours, le code source complet peut être trouvéover on GitHub.