Separate Spring DataSource für Tests konfigurieren

Separate Spring DataSource für Tests konfigurieren

1. Überblick

Wenn Sie eine Spring-Anwendung testen, die auf einer Persistenzschicht wie JPA basiert, möchten Sie möglicherweise eine Testdatenquelle einrichten, die eine kleinere, schnellere Datenbank verwendet - eine Datenbank, die sich von der unterscheidet, die zum Ausführen der Anwendung verwendet wird um die Durchführung unserer Tests zu vereinfachen.

Zum Konfigurieren einer Datenquelle in Spring muss eine Bean vom TypDataSourceentweder manuell oder bei Verwendung von Spring Boot über Standardanwendungseigenschaften definiert werden.

In diesem kurzen Tutorial werfen wir einen Blick aufseveral ways to configure a separate data source for testing in Spring.

2. Maven-Abhängigkeiten

Wir werden eine Spring Boot-Anwendung mit Spring JPA erstellen und testen, daher benötigen wir die folgenden Abhängigkeiten:


    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

Die neuesten Versionen vonspring-boot-starter-data-jpa,h2 undspring-boot-starter-test können von Maven Central heruntergeladen werden.

Schauen wir uns einige verschiedene Möglichkeiten an, umDataSource zum Testen zu konfigurieren.

3. Verwenden einer Standardeigenschaftendatei im Spring Boot

Die Standardeigenschaftendatei, die Spring Boot beim Ausführen einer Anwendung automatisch abruft, heißtapplication.properties und befindet sich im Ordnersrc/main/resources.

Wenn wir verschiedene Eigenschaften für Tests verwenden möchten, können wir die Eigenschaftendatei im Ordnermain überschreiben, indem wir eine andere Datei mit demselben Namen insrc/test/resources ablegen.

Dieapplication.properties-Datei imsrc/test/resources-Ordner sollte die Standard-Schlüssel-Wert-Paare enthalten, die zum Konfigurieren einer Datenquelle erforderlich sind. Diesen Eigenschaften wirdspring.datasource vorangestellt.

Konfigurieren Sie beispielsweise eine speicherinterneH2-Datenbank als Datenquelle für 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 verwendet diese Eigenschaften, um eineDataSource-Bean automatisch zu konfigurieren.

Definieren wir mit Spring JPA ein sehr einfachesGenericEntity und Repository:

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

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

Als nächstes schreiben wir einenJUnit-Test für das Repository. Damit ein Test in einer Spring Boot-Anwendung die von uns definierten Standarddatenquelleneigenschaften abrufen kann, muss er mit@SpringBootTest versehen werden:

@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. Verwenden einer benutzerdefinierten Eigenschaftendatei

Wenn wir die Standarddatei und -schlüssel vonapplication.propertiesnicht verwenden möchten oder wenn wir Spring Boot nicht verwenden, können wir eine benutzerdefinierte.properties-Datei mit benutzerdefinierten Schlüsseln definieren und diese Datei dann in a lesen @Configuration Klasse, um eineDataSource Bean basierend auf den darin enthaltenen Werten zu erstellen.

Diese Datei wird für den normalen Ausführungsmodus der Anwendung im Ordnersrc/main/resourcesund insrc/test/resources abgelegt, um von Tests erfasst zu werden.

Erstellen wir eine Datei mit dem Namenpersistence-generic-entity.properties, die eine speicherinterneH2-Datenbank für Tests verwendet, und legen Sie sie im Ordnersrc/test/resources ab:

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

Als Nächstes können wir dieDataSource-Bean basierend auf diesen Eigenschaften in einer@Configuration-Klasse definieren, die unserepersistence-generic-entity.properties als Eigenschaftsquelle lädt:

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

Ein detaillierteres Beispiel für diese Konfiguration finden Sie in unserem vorherigen Artikel zuSelf-contained testing with an in-memory database im Abschnitt „JPA-Konfiguration“.

Dann können wir einenJUnit-Test erstellen, der dem vorherigen ähnlich ist, außer dass unsere Konfigurationsklasse geladen wird:

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

5. Verwenden von Federprofilen

Eine andere Möglichkeit, ein separatesDataSource zum Testen zu konfigurieren, besteht darin, mithilfe von Spring Profiles eineDataSource-Bean zu definieren, die nur in einemtest-Profil verfügbar ist.

Dazu können wir wie zuvor eine.properties-Datei verwenden oder die Werte in die Klasse selbst schreiben.

Definieren wir eineDataSource-Bean für dastest-Profil in einer@Configuration-Klasse, die von unserem Test geladen wird:

@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
}

Dann müssen wir in der TestklasseJUnitangeben, dass wir das Profil vontestverwenden möchten, indem wir die Annotation@ActiveProfileshinzufügen:

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

6. Fazit

In diesem kurzen Tutorial haben wir verschiedene Möglichkeiten gesehen, wie wir separateDataSource für Tests im Frühjahr konfigurieren können.

Wie immer finden Sie den vollständigen Quellcode der Beispiele inover on GitHub.