Configuring Separate Spring DataSource for Tests – 为测试配置独立的Spring DataSource

最后修改: 2017年 4月 9日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

When testing a Spring application that relies on a persistence layer, such as JPA, we may want to set up a test data source to use a smaller, faster database different from the one we use to run the application, in order to make running our tests much easier.

当测试一个依赖持久层的Spring应用程序时,比如JPA,我们可能想设置一个测试数据源,使用一个与我们用来运行应用程序的数据库不同的更小、更快的数据库,以使我们的测试更容易运行。

Configuring a data source in Spring requires defining a bean of type DataSource. We can do this either manually, or if using Spring Boot, through standard application properties.

在Spring中配置数据源需要定义一个DataSource类型的bean。我们可以手动完成这项工作,如果使用Spring Boot,也可以通过标准的应用程序属性完成。

In this quick tutorial, we’ll learn several ways to configure a separate data source for testing in Spring.

在这个快速教程中,我们将学习几种在Spring中为测试配置独立数据源的方法

2. Maven Dependencies

2.Maven的依赖性

We’re going to create a Spring Boot application using Spring JPA and testing, so we’ll need the following dependencies:

我们将使用Spring JPA和测试来创建一个Spring Boot应用程序,因此我们需要以下依赖性。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> 
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

The latest versions of spring-boot-starter-data-jpa, h2, and spring-boot-starter-test can be downloaded from Maven Central.

spring-boot-starter-data-jpah2spring-boot-starter-test的最新版本可以从Maven中心下载。

Now let’s look at a few different ways to configure a DataSource for testing.

现在让我们来看看配置DataSource的几种不同方法,以便进行测试。

3. Using a Standard Properties File in Spring Boot

3.在Spring Boot中使用标准属性文件

The standard properties file that Spring Boot picks up automatically when running an application is called application.properties. It resides in the src/main/resources folder.

Spring Boot在运行应用程序时自动获取的标准属性文件称为application.properties.,它位于src/main/resources文件夹中。

If we want to use different properties for tests, we can override the properties file in the main folder by placing another file with the same name in src/test/resources.

如果我们想在测试中使用不同的属性,我们可以通过在src/test/resources中放置一个同名的文件来覆盖main文件夹中的属性文件。

The application.properties file in the src/test/resources folder should contain the standard key-value pairs necessary for configuring a data source. These properties are prefixed with spring.datasource.

application.properties文件在src/test/resources文件夹中应包含配置数据源所需的标准键值对。这些属性的前缀是spring.datasource

For example, let’s configure an H2 in-memory database as a data source for tests:

例如,让我们配置一个H2内存数据库作为测试的数据源。

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 will use these properties to automatically configure a DataSource bean.

Spring Boot将使用这些属性来自动配置一个DataSourcebean。

Let’s define a very simple GenericEntity and repository using Spring JPA:

让我们使用Spring JPA定义一个非常简单的GenericEntity和存储库。

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

    //standard constructors, getters, setters
}
public interface GenericEntityRepository
  extends JpaRepository<GenericEntity, Long> { }

Next, let’s write a JUnit test for the repository. In order for a test in a Spring Boot application to pick up the standard data source properties we defined, we have to annotate it with @SpringBootTest:

接下来,让我们为资源库写一个JUnit测试。为了让Spring Boot应用程序中的测试能够获取我们定义的标准数据源属性,我们必须用@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. Using a Custom Properties File

4.使用自定义属性文件

If we don’t want to use the standard application.properties file and keys, or if we’re not using Spring Boot, we can define a custom .properties file with custom keys, then read this file in a @Configuration class to create a DataSource bean based on the values it contains.

如果我们不想使用标准的application.properties文件和键,或者不使用Spring Boot,我们可以定义一个带有自定义键的自定义.properties文件,然后在@Configuration类中读取该文件,根据其中包含的值创建一个DataSourcebean。

This file will be placed in the src/main/resources folder for the normal running mode of the application, and in src/test/resources in order to be picked up by tests.

在应用程序的正常运行模式下,该文件将被放置在src/main/resources文件夹中,而在src/test/resources中,以便被测试所接收。

Let’s create a file called persistence-generic-entity.properties that uses an H2 in-memory database for tests, and place it in the src/test/resources folder:

让我们创建一个名为persistence-generic-entity.properties的文件,该文件使用H2内存数据库进行测试,并将其放在 src/test/resources文件夹中。

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

Next, we can define the DataSource bean based on these properties in a @Configuration class that loads our persistence-generic-entity.properties as a property source:

接下来,我们可以在@Configuration类中基于这些属性定义DataSource Bean,该类将我们的persistence-generic-entity.properties作为属性源加载。

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

For a more detailed example of this configuration, we can read through the section “JPA Configuration” in our previous article on Self-contained testing with an in-memory database.

关于这种配置的更详细的例子,我们可以通读我们之前关于使用内存数据库进行自含测试的文章中的 “JPA配置 “部分

Then we can create a JUnit test similar to the previous one, except it’ll load our configuration class:

然后我们可以创建一个JUnit测试,与之前的测试类似,只不过它将加载我们的配置类。

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

5. Using Spring Profiles

5.使用Spring Profiles

Another way we can configure a separate DataSource for testing is by leveraging Spring Profiles to define a DataSource bean that’s only available in a test profile.

我们为测试配置单独的DataSource的另一种方式是利用Spring Profiles来定义一个DataSource Bean,它只在test profile中可用。

For this, we can use a .properties file, as before, or we can write the values in the class itself.

为此,我们可以像以前一样使用.properties文件,也可以把值写在类本身。

Let’s define a DataSource bean for the test profile in a @Configuration class that will be loaded by our test:

让我们在@Configuration类中为test配置文件定义一个DataSource bean,该类将被我们的测试加载。

@Configuration
@EnableJpaRepositories(basePackages = {
  "org.baeldung.repository",
  "org.baeldung.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
}

Then, in the JUnit test class, we need to specify that we want to use the test profile by adding the @ActiveProfiles annotation:

然后,在JUnit测试类中,我们需要通过添加@ActiveProfiles注释来指定我们要使用test配置文件。

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

6. Conclusion

6.结论

In this brief article, we explored several ways to configure a separate DataSource for testing in Spring.

在这篇简短的文章中,我们探讨了几种在Spring中配置单独的DataSource进行测试的方法。

As always, the full source code of the examples can be found over on GitHub.

一如既往,可以在GitHub上找到这些例子的完整源代码