Java >> Java Tutorial >  >> Tag >> Spring

Spring Data JPA-Lernprogramm:Integrationstests

Mein Spring Data JPA-Tutorial hat uns gelehrt, dass wir Datenbankabfragen erstellen und Entitäten in der Datenbank beibehalten können, indem wir spezielle Repository-Schnittstellen verwenden.

Dies wirft eine interessante Frage auf:

Wie können wir Integrationstests für unsere Spring Data JPA-Repositories schreiben, da sie doch nur Schnittstellen sind?

Dieser Blogbeitrag beantwortet diese Frage. In diesem Blogbeitrag werden wir Integrationstests für ein Spring Data JPA-Repository schreiben, das die Informationen von Aufgabeneinträgen verwaltet (Todo Gegenstände). Genauer gesagt werden wir Integrationstests für findBySearchTerm() schreiben Methode von TodoRepository Schnittstelle. Diese Methode ignoriert Groß- und Kleinschreibung und gibt Aufgabeneinträge zurück, deren Titel oder Beschreibung den angegebenen Suchbegriff enthält.

Beginnen wir damit, die erforderlichen Abhängigkeiten mit Maven zu erhalten.

Erforderliche Abhängigkeiten mit Maven abrufen

Wir können die erforderlichen Abhängigkeiten mit Maven erhalten, indem wir die folgenden Abhängigkeiten in unserer pom.xml deklarieren Datei:

  • JUnit (Version 4.11).
  • AssertJ Core (Version 3.2.0). Wir verwenden AssertJ, um sicherzustellen, dass die getestete Methode die richtigen Informationen zurückgibt.
  • Frühjahrstest (Version 4.1.6.RELEASE).
  • DbUnit (Version 2.5.1). Denken Sie daran, die JUnit-Abhängigkeit auszuschließen. Wir verwenden DbUnit, um unsere Datenbank in einen bekannten Zustand zu initialisieren, bevor jeder Testfall aufgerufen wird.
  • Spring Test DbUnit (Version 1.2.1) integriert DbUnit in das Spring Test-Framework.

Der relevante Teil unserer pom.xml Datei sieht wie folgt aus:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.11</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.assertj</groupId>
	<artifactId>assertj-core</artifactId>
	<version>3.2.0</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>4.1.6.RELEASE</version>
	<scope>test</scope>
</dependency>
<dependency>
	<groupId>org.dbunit</groupId>
	<artifactId>dbunit</artifactId>
	<version>2.5.1</version>
	<scope>test</scope>
	<exclusions>
		<exclusion>
			<artifactId>junit</artifactId>
			<groupId>junit</groupId>
		</exclusion>
	</exclusions>
</dependency>
<dependency>
	<groupId>com.github.springtestdbunit</groupId>
	<artifactId>spring-test-dbunit</artifactId>
	<version>1.2.1</version>
	<scope>test</scope>
</dependency>

Nachdem wir die benötigten Abhängigkeiten in unserer pom.xml konfiguriert haben Datei können wir unsere Integrationstests konfigurieren.

Konfigurieren unserer Integrationstests

Wir können unsere Integrationstests konfigurieren, indem wir diesen Schritten folgen:

  1. Führen Sie Integrationstests mit SpringJUnit4ClassRunner durch Klasse. Es ist ein benutzerdefinierter JUnit-Runner, der das Spring Test-Framework mit JUnit integriert. Wir können den verwendeten JUnit-Runner konfigurieren, indem wir unsere Testklasse mit @RunWith kommentieren Anmerkung.
  2. Konfigurieren Sie die Anwendungskontext-Konfigurationsklasse (oder XML-Konfigurationsdatei), die den Anwendungskontext konfiguriert, der von unseren Integrationstests verwendet wird. Wir können die verwendete Anwendungskontext-Konfigurationsklasse (oder XML-Konfigurationsdatei) konfigurieren, indem wir unsere Testklasse mit @ContextConfiguration kommentieren Anmerkung.
  3. Konfigurieren Sie die Testausführungs-Listener, die auf die vom Spring Test-Framework veröffentlichten Testausführungsereignisse reagieren. Wir müssen die folgenden Testausführungs-Listener konfigurieren:
    • Der DependencyInjectionTestExecutionListener bietet Abhängigkeitsinjektion für das Testobjekt.
    • Der TransactionalTestExecutionListener fügt Transaktionsunterstützung (mit standardmäßiger Rollback-Semantik) zu unseren Integrationstests hinzu.
    • Der DbUnitTestExecutionListener Fügt Unterstützung für die Funktionen hinzu, die von der Spring Test DbUnit-Bibliothek bereitgestellt werden.

Nachdem wir diese Konfiguration zu unserer Integrationstestklasse hinzugefügt haben, sieht ihr Quellcode wie folgt aus:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class})
public class ITFindBySearchTermTest {
}

Nachdem wir unsere Integrationstestklasse konfiguriert haben, können wir mit dem Schreiben von Integrationstests für unser Spring Data JPA-Repository beginnen.

Schreiben von Integrationstests für unser Repository

Wir können Integrationstests für unser Repository schreiben, indem wir diesen Schritten folgen:

Zuerst , müssen wir das getestete Repository in unsere Testklasse einfügen. Weil wir Integrationstests für das TodoRepository schreiben Schnittstelle, müssen wir es in unsere Testklasse einfügen. Der Quellcode unserer Testklasse sieht wie folgt aus:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class})
public class ITFindBySearchTermTest {

	@Autowired
	private TodoRepository repository;
}

Zweiter , müssen wir das DbUnit-Dataset erstellen, das unsere Datenbank in einen bekannten Zustand initialisiert, bevor unsere Testfälle aufgerufen werden. Wir verwenden das flache XML-Dataset-Format, da es weniger ausführlich ist als das ursprüngliche DbUnit-Dataset-Format. Das bedeutet, dass wir unseren Datensatz erstellen können, indem wir diesen Regeln folgen:

  • Jedes XML-Element enthält die Informationen einer einzelnen Tabellenzeile.
  • Der Name des XML-Elements identifiziert den Namen der Datenbanktabelle, in die seine Informationen eingefügt werden.
  • Die Attribute des XML-Elements spezifizieren die Werte, die in die Spalten der Datenbanktabelle eingefügt werden.

Das getestete Repository (TodoRepository ) fragt Informationen aus den Aufgaben ab Tabelle mit den folgenden Spalten:id , erstellt_von_Benutzer , creation_time , Beschreibung , modified_by_user , modification_time , Titel und Version .

Weil wir Integrationstests für eine Methode schreiben, die eine Liste von Todo zurückgibt Objekten möchten wir zwei Zeilen in die Aufgaben einfügen Tisch. Wir können dies tun, indem wir eine DbUnit-Datensatzdatei erstellen (todo-entries.xml ), die wie folgt aussieht:

<dataset>
    <todos id="1"
           created_by_user="createdByUser"
           creation_time="2014-12-24 11:13:28"
           description="description"
           modified_by_user="modifiedByUser"
           modification_time="2014-12-25 11:13:28"
           title="title"
           version="0"/>
    <todos id="2"
           created_by_user="createdByUser"
           creation_time="2014-12-24 11:13:28"
           description="tiscription"
           modified_by_user="modifiedByUser"
           modification_time="2014-12-25 11:13:28"
           title="Foo bar"
           version="0"/>
</dataset>

Dritter , können wir Integrationstests für findBySearchTerm() schreiben Methode des TodoRepository Schnittstelle. Lassen Sie uns Integrationstests schreiben, die sicherstellen, dass findBySearchTerm() -Methode funktioniert korrekt, wenn der Titel eines Aufgabeneintrags den angegebenen Suchbegriff enthält. Wir können diese Integrationstests schreiben, indem wir diesen Schritten folgen:

  1. Konfigurieren Sie die verwendete Datensatzdatei, indem Sie die Integrationstestklasse mit @DatabaseSetup kommentieren Anmerkung.
  2. Schreiben Sie einen Integrationstest, der sicherstellt, dass findBySearchTerm() Die Methode gibt einen Todo-Eintrag zurück, wenn der Suchbegriff "iTl" als Methodenparameter übergeben wird.
  3. Schreiben Sie einen Integrationstest, der sicherstellt, dass findBySearchTerm() Methode gibt den "ersten" Todo-Eintrag zurück, wenn der Suchbegriff "iTl" als Methodenparameter übergeben wird.

Der Quellcode von ITFindBySearchTerm Klasse sieht wie folgt aus:

import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {PersistenceContext.class})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class})
@DatabaseSetup("todo-entries.xml")
public class ITFindBySearchTermTest {

	@Autowired
	private TodoRepository repository;
	
	@Test
	public void findBySearchTerm_TitleOfFirstTodoEntryContainsGivenSearchTerm_ShouldReturnOneTodoEntry() {
		List<Todo> searchResults = repository.findBySearchTerm("iTl");
		assertThat(searchResults).hasSize(1);
	}
	
	@Test
	public void findBySearchTerm_TitleOfFirstTodoEntryContainsGivenSearchTerm_ShouldReturnFirstTodoEntry() {
		List<Todo> searchResults = repository.findBySearchTerm("iTl");

		Todo found = searchResults.get(0);
		assertThat(found.getId()).isEqualTo(1L);
	}	
}

Fahren wir fort und fassen zusammen, was wir aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat uns vier Dinge gelehrt:

  • Wir können DbUnit mit dem Spring Test-Framework integrieren, indem wir Spring Test DbUnit verwenden.
  • Wir können Spring Test DbUnit mit dem Spring Test-Framework integrieren, indem wir den DbUnitTestExecutionListener verwenden Klasse.
  • Wir sollten das flache XML-Datenbankformat verwenden, da es weniger ausführlich ist als das ursprüngliche DbUnit-Datensatzformat.
  • Wir können das @DatabaseSetup verwenden Annotation auf Klassenebene oder auf Methodenebene.

P.S. Sie können die Beispielanwendungen dieses Blogbeitrags von Github erhalten (Abfragemethoden, JPA Criteria API, Querydsl).


Java-Tag