[JAVA] Utiliser DBUnit pour le test Spring Boot

Abstrait

Utilisez dbunit pour tester votre projet Spring Boot.

environnement

supposition

Cible de test

colonne Moule Clé primaire
person_id integer
person_name character varying(20)
birth_date date
birth_place character varying(20)

J'ai créé le mappeur suivant avec MyBatis pour la table.

@Mapper
public interface PersonMapper {

	@Select("SELECT * FROM person WHERE person_id = #{personId}")
	public Person selectById(int personId);

	@Insert("INSERT INTO person(person_id, person_name, birth_date, birth_place) VALUES (#{person_id}, #{person_name}, #{birth_date}, #{birth_place})")
	public void insert(Person person);
}

Procédure détaillée

Ajouter une dépendance

Ajoutez spring-test-dbunit et dbunit aux dépendances.

pom.xml


<dependency>
  <groupId>com.github.springtestdbunit</groupId>
  <artifactId>spring-test-dbunit</artifactId>
  <version>1.3.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.dbunit</groupId>
  <artifactId>dbunit</artifactId>
  <version>2.6.0</version>
  <scope>test</scope>
</dependency>

Saisie des données préalables

Écrivez les données dans le DB avant d'exécuter le test (avant d'exécuter la méthode de test).

Modèle de base

__ * Dans les cas suivants, les données utilisées pour le test seront validées __ (Le cas de rollback sera décrit plus loin)

Description des données d'entrée

Motif A.xml


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<person person_id="1" person_name="Suzaki" birth_date="1986-12-25" />
	<person person_id="2" person_name="Nishi"                          birth_place="Préfecture de Hyogo" />
	<person person_id="3"                      birth_date="1994-02-22" birth_place="Tokyo" />
</dataset>
Création de classe de test
// (1)
@RunWith(SpringRunner.class)
@SpringBootTest
@TestExecutionListeners({
	DependencyInjectionTestExecutionListener.class,
	DbUnitTestExecutionListener.class
})
public class PersonMapperTest {

	@Autowired // (2)
	PersonMapper mapper;

	@Test
	@DatabaseSetup("/dbunit/Motif A.xml") // (3)
	public void test() {
		//Écrire le code de test
	}
}
(1) Écrivez toutes les annotations ci-dessus dans la classe de test
(2) Autowired est possible pour démarrer Spring
(3) Dans la méthode de test@DatabaseSetupEt décrivez le chemin xml dans son argument
Résultat d'exécution
# SELECT * FROM person;
person_id | person_name | birth_date | birth_place
-----------+-------------+------------+-------------
        1 | Suzaki      | 1986-12-25 |
        2 | Nishi       |            |Préfecture de Hyogo
        3 |             | 1994-02-22 |Tokyo
(3 lignes)

Modèle d'entrée vide

Description des données d'entrée

Si vous écrivez une balise sans attributs comme indiqué ci-dessous, seul DELETE sera exécuté et la table sera vide.

Motif B.xml


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<person />
</dataset>
Résultat d'exécution
# SELECT * FROM person;
 person_id | person_name | birth_date | birth_place
-----------+-------------+------------+-------------
(0 ligne)

Modèle d'entrée de caractère vide

Description des données d'entrée

Modèle C.xml


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<person person_id="4" person_name="" birth_date="1991-12-25" birth_place="Préfecture de Hyogo" />
</dataset>

Si le xml ci-dessus est en lecture seule avec le code de test de modèle de base, l'exception suivante se produit. java.lang.IllegalArgumentException: table.column=person.person_name value is empty but must contain a value (to disable this feature check, set DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS to true)

Code supplémentaire

Ajoutez la configuration suivante au chemin lu lors de l'exécution du test.

@Configuration
public class DatasourceConfig {

	// (1)
	@Bean
	public DatabaseConfigBean dbUnitDatabaseConfig() {
		DatabaseConfigBean bean = new DatabaseConfigBean();

		bean.setAllowEmptyFields(true); // (2)

		return bean;
	}

	// (3)
	@Bean
	public DatabaseDataSourceConnectionFactoryBean dbUnitDatabaseConnection(
			DatabaseConfigBean dbUnitDatabaseConfig,
			DataSource dataSource
	) {
		DatabaseDataSourceConnectionFactoryBean bean = new DatabaseDataSourceConnectionFactoryBean(dataSource);
		bean.setDatabaseConfig(dbUnitDatabaseConfig);
		return bean;
	}
}
(1) Enregistrez la configuration d'exécution en tant que bean
(2) Activez le commutateur qui autorise les caractères vides(Le défaut est faux)
(3) (1)Refléter les paramètres de la source de données utilisée dans Spring
Résultat d'exécution
# SELECT * FROM person;
person_id | person_name | birth_date | birth_place
-----------+-------------+------------+-------------
        4 |             | 1991-12-25 |Préfecture de Hyogo
(1 ligne)
@Test
@DatabaseSetup("/dbunit/Modèle C.xml")
public void test() {
  Person actual = mapper.selectById(4);
  assertThat(actual.getPerson_name()).isEqualTo(""); // ->Succès
}

Modèle pour renvoyer les données après le test

Création de classe de test

Ajoutez des écouteurs et des annotations au modèle de base.

@RunWith(SpringRunner.class)
@SpringBootTest
@TestExecutionListeners({
	DependencyInjectionTestExecutionListener.class,
	TransactionalTestExecutionListener.class, // (1)
	DbUnitTestExecutionListener.class
})
@Transactional //(2)
public class PersonMapperTest3 {
  ...
}
(1) Ajouter un écouteur pour la gestion des transactions
(2) L'unité qui gère réellement la transaction(Fondamentalement classe)alors@TransactionalSubvention

Vous pouvez également ajouter «@ Transactional» à la méthode.

@Test
@Transactional
@DatabaseSetup("/dbunit/Motif A.xml")
public void test() {
  ...
}

Évitez le texte d'avertissement

Lorsqu'il est exécuté avec le modèle ci-dessus, le journal suivant est généré au niveau WARN. Potential problem found: The configured data type factory 'class org.dbunit.dataset.datatype.DefaultDataTypeFactory' might cause problems with the current database 'PostgreSQL' (e.g. some datatypes may not be supported properly). In rare cases you might see this message because the list of supported database products is incomplete (list=[derby]). If so please request a java-class update via the forums.If you are using your own IDataTypeFactory extending DefaultDataTypeFactory, ensure that you override getValidDbProducts() to specify the supported database products.

Étant donné que le journal indique que DataTypeFactory n'est pas spécifié, ajoutez la description suivante à la classe de configuration utilisée dans le modèle d'entrée de caractère vide.

@Bean
public DatabaseConfigBean dbUnitDatabaseConfig() {
  DatabaseConfigBean bean = new DatabaseConfigBean();

  bean.setAllowEmptyFields(true);
  bean.setDatatypeFactory(new PostgresqlDataTypeFactory()); // (1)

  return bean;
}
(1) Puisque PostgreSQL est utilisé, le DataTypeFactory pour PostgreSQL fourni par dbunit est spécifié.

Définition des données supposées

Modèle de base

Description des données supposées

Décrivez dans le même format que les données préalables. Lorsque des caractères nuls ou vides sont supposés, c'est le même que l'entrée de données prérequises.

Modèle D.xml


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<person person_id="1" person_name="Suzaki" birth_date="1986-12-25" />
	<person person_id="2" person_name="Nishi"                          birth_place="Préfecture de Hyogo" />
	<person person_id="3"                      birth_date="1994-02-22" birth_place="" />
</dataset>

Résultat présumé 1.xml


<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<person person_id="1" person_name="Suzaki" birth_date="1986-12-25" />
	<person person_id="2" person_name="Nishi"                          birth_place="Préfecture de Hyogo" />
	<person person_id="3"                      birth_date="1994-02-22" birth_place="" />
	<person person_id="11" person_name="Uesaka" birth_date="1991-12-19" birth_place="Préfecture de Kanagawa" />
</dataset>
Création de méthode de test
@Test
@DatabaseSetup("/dbunit/Modèle D.xml")
@ExpectedDatabase(
	value="/dbunit/Résultat présumé 1.xml",
	assertionMode=DatabaseAssertionMode.NON_STRICT
) // (1)
public void test() {
	Person param = new Person();
	param.setPerson_id(11);
	param.setPerson_name("Uesaka");
	param.setBirth_date(new Date(91, 11, 19));
	param.setBirth_place("Préfecture de Kanagawa");

	mapper.insert(param);
}
(1) Décrivez une annotation qui spécifie le résultat attendu. Par défaut, toutes les tables sont vérifiées, mais assertionMode=NON_Avec STRICT, seule la table décrite en xml est inspectée.

Site de référence

SpringBoot 45.Testing Méthode d'implémentation du test de Spring Framework Unit 1-3. Test du référentiel (Junit4, spring-test, DBUnit) │ ヰ Boîte à jouets Sword How to set default properties in spring dataset DatabaseConfig - Stack Overflow

Recommended Posts

Utiliser DBUnit pour le test Spring Boot
Utilisez Spring Test + Mockito + JUnit 4 pour le test unitaire Spring Boot + Spring Retry
Spring Boot + Springfox springfox-boot-starter 3.0.0 Utilisation
Utiliser Spring JDBC avec Spring Boot
Spring Boot pour l'apprentissage des annotations
Comment écrire un test unitaire pour Spring Boot 2
Utiliser l'authentification de base avec Spring Boot
Spring Boot pour la première fois
Annotations fréquentes pour les tests Spring Boot
Comment utiliser ModelMapper (Spring boot)
À partir de Spring Boot 0. Utilisez Spring CLI
Écrivons un code de test pour la fonction de connexion avec Spring Boot
Effectuer un test de confirmation de transaction avec Spring Boot
Le test Spring Boot @WebMvcTest active la sécurité par défaut de Spring Security
Mémorandum WebMvcConfigurer de Spring Boot 2.0 (printemps 5)
Utiliser le cache avec EhCashe 2.x avec Spring Boot
Test de validation de classe de formulaire avec Spring Boot
Défi Spring Boot
Forme de botte de printemps
Spring Boot Rappelez-vous
[Pour usage interne] Pour ceux affectés au projet Spring Boot (en construction)
gae + botte à ressort
À propos de la conception de Spring Boot et de l'environnement de test unitaire
Testez le contrôleur avec Mock MVC dans Spring Boot
Utilisez le mode de modèle de texte Thymeleaf de Spring Boot
Comment utiliser MyBatis2 (iBatis) avec Spring Boot 1.4 (Spring 4)
Comment utiliser h2db intégré avec Spring Boot
Utiliser le filtre de servlet avec Spring Boot [compatible Spring Boot 1.x, 2.x]
Remarques sur les annotations lors de l'écriture de tests pour Spring Boot
Comment effectuer UT avec Excel en tant que données de test avec Spring Boot + JUnit5 + DBUnit
Plans pour prendre en charge JDK 11 pour Eclipse et Spring Boot
Paramètres de connexion à MySQL avec Spring Boot + Spring JDBC
Fiche d'apprentissage SPRING BOOT 01
Botte de printemps + Heroku Postgres
Rédaction de mémo de démarrage de printemps (1)
[Compatible JUnit 5] Ecrire un test en utilisant JUnit 5 avec Spring boot 2.2, 2.3
Première botte à ressort (DI)
Fiche d'apprentissage SPRING BOOT 02
[Spring Boot] Comment créer un projet (pour les débutants)
Aide-mémoire Spring Boot2
Customizer pour Platform Transaction Manager ajouté à partir de Spring Boot 1.5
Gestion des exceptions Spring Boot
Mappage du servlet Spring Boot
Environnement de développement-développement Spring Boot-
Procédure d'apprentissage Spring Boot
[JUnit 5] Ecrivez un test de validation avec Spring Boot! [Test de paramétrage]
Apprentissage de Spring Boot [Début]
Rédaction de mémos de démarrage de printemps (2)
Résumé du document Spring Boot 2.2
Testez la classe injectée sur le terrain dans le test de démarrage Spring sans utiliser le conteneur Spring
[Spring Boot] DataSourceProperties $ DataSourceBeanCreationException
Disponibilité de l'application Spring Boot 2.3
Tutoriels Spring Boot Sujets
J'ai écrit un test avec Spring Boot + JUnit 5 maintenant
Téléchargement de fichiers avec Spring Boot (ne pas utiliser de fichier en plusieurs parties)
Télécharger avec Spring Boot
Étapes requises pour émettre des événements asynchrones Spring Boot
Changez la cible d'injection pour chaque environnement avec Spring Boot 2
Comment appeler et utiliser l'API en Java (Spring Boot)
Une introduction pratique pour les débutants de Spring 5 et Spring Boot 2 a été publiée
Utilisez thymeleaf3 avec le parent sans spécifier spring-boot-starter-parent dans Spring Boot