概述

通常,我们使用Spring的自动配置系统,如@SpringBootTest,来测试Spring Boot应用。然而,这会导致导入大量自动配置的组件。

然而,为了只加载需要的部分以测试应用的某个切片,Spring Boot提供了许多用于片段测试的注解。每个这些Spring注解都会加载特定层所需的一小部分自动配置组件。

在这篇教程中,我们将重点测试Spring Boot应用中的Cassandra数据库片段,从而了解Spring提供的@DataCassandraTest注解。

此外,我们将观察一个基于Cassandra的简单Spring Boot应用的实际运行情况。如果你在生产环境中运行Cassandra,你可以完全省去运行和维护自己的服务器的复杂性,转而使用基于Apache Cassandra的云数据库Astra数据库

2. Maven依赖

要在Cassandra Spring Boot应用中使用@DataCassandraTest注解,我们需要添加spring-boot-starter-test依赖:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.5.3</version>
    <scope>test</scope>
</dependency>

Spring的spring-boot-test-autoconfigurespring-boot-starter-test库的一部分,它包含了许多用于测试应用不同切片的自动配置组件。

通常,这种测试注解的模式是 @XXXTest

@DataCassandraTest注解导入了以下Spring数据自动配置组件:

  • CacheAutoConfiguration
  • CassandraAutoConfiguration
  • CassandraDataAutoConfiguration
  • CassandraReactiveDataAutoConfiguration
  • CassandraReactiveRepositoriesAutoConfiguration
  • CassandraRepositoriesAutoConfiguration

3. 示例Cassandra Spring Boot应用

为了说明这些概念,我们有一个简单的Spring Boot Web应用,其主要领域是车辆库存。

为了简化,这个应用提供了库存数据的基本 CRUD 操作。

3.1. Cassandra Maven依赖

Spring提供了spring-boot-starter-data-cassandra模块来处理Cassandra数据:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-cassandra</artifactId>
    <version>2.5.3</version>
</dependency>

我们还需要Datastax Cassandra的java-driver-core依赖,以便建立与Cassandra集群的连接并执行请求:

<dependency> 
    <groupId>com.datastax.oss</groupId> 
    <artifactId>java-driver-core</artifactId> 
    <version>4.13.0</version> 
</dependency>

3.2. Cassandra配置

这里的CassandraConfig类继承自Spring的AbstractCassandraConfiguration,这是Spring Data Cassandra配置的基础类。

这个Spring类用于配置Cassandra客户端应用,以 CqlSession 连接到Cassandra集群。

此外,我们可以配置键空间名称和集群主机:

@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Override
    protected String getKeyspaceName() {
        return "inventory";
    }

    @Override
    public String getContactPoints() {
        return "localhost";
    }

    @Override
    protected String getLocalDataCenter() {
         return "datacenter1";
    }
}

4. 数据模型

以下Cassandra查询语言(CQL)通过名称inventory创建Cassandra键空间:

CREATE KEYSPACE inventory
WITH replication = {
    'class' : 'NetworkTopologyStrategy',
    'datacenter1' : 3
};

这个CQL创建名为vehicles的Cassandra表在inventory键空间中:

use inventory;

CREATE TABLE vehicles (
   vin text PRIMARY KEY,
   year int,
   make varchar,
   model varchar
);

5. 使用 @DataCassandraTest ****

让我们看看如何在单元测试中使用@DataCassandraTest来测试应用的数据层。

@DataCassandraTest注解导入所需的Cassandra自动配置模块,包括扫描@Table@Repository组件。因此,它可以自动注入Repository类。

然而,它不会扫描和导入常规的@Component@ConfigurationProperties bean。

此外,对于JUnit 4,此注解应与@RunWith(SpringRunner.class)一起使用。

5.1. 集成测试类

下面是带有@DataCassandraTest注解和@AutowiredInventoryServiceIntegrationTest类:

@RunWith(SpringRunner.class)
@DataCassandraTest
@Import(CassandraConfig.class)
public class InventoryServiceIntegrationTest {

    @Autowired
    private InventoryRepository repository;

    @Test
    public void givenVehiclesInDBInitially_whenRetrieved_thenReturnAllVehiclesFromDB() {
        List<Vehicle> vehicles = repository.findAllVehicles();

        assertThat(vehicles).isNotNull();
        assertThat(vehicles).isNotEmpty();
    }
}

我们还在此上方添加了一个简单的测试方法。为了更容易运行这个测试,我们将使用DockerCompose Test Container,它设置了一个三节点的Cassandra集群:

public class InventoryServiceLiveTest {

    // ...

    public static DockerComposeContainer container =
            new DockerComposeContainer(new File("src/test/resources/compose-test.yml"));

    @BeforeAll
    static void beforeAll() {
        container.start();
    }

    @AfterAll
    static void afterAll() {
        container.stop();
    }
}

你可以在GitHub项目这里找到compose-test.yml文件。

5.2. 仓库类

示例仓库类InventoryRepository定义了一些自定义的JPA方法:

@Repository
public interface InventoryRepository extends CrudRepository<Vehicle, String> {

    @Query("select * from vehicles")
    List<Vehicle> findAllVehicles();

    Optional<Vehicle> findByVin(@Param("vin") String vin);

    void deleteByVin(String vin);
}

我们还将一致性级别设置为“local-quorum”,这意味着强一致性,只需在application.yml文件中添加此属性:

spring:
  data:
    cassandra:
      request:
        consistency: local-quorum

6. 其他 @DataXXXTest 注解

以下是其他类似注解,用于测试任何应用的数据层:

  • @DataJpaTest 引入JPA仓库、@Entity 类等。
  • @DataJdbcTest 引入Spring Data仓库、JdbcTemplate等。
  • @DataMongoTest 引入Spring Data MongoDB仓库、Mongo模板和@Document
  • @DataNeo4jTest 引入Spring Data Neo4j仓库、@Node
  • @DataRedisTest 引入Spring Data Redis仓库、@RedisHash

请访问Spring文档获取更多测试注解和详细信息。

7. 总结

在这篇文章中,我们了解了@DataCassandraTest注解如何加载几个Spring Data Cassandra的自动配置组件。结果,它避免了加载许多不需要的Spring上下文模块。

如往常一样,完整的源代码可在GitHub上获取。