一、概述
Testcontainers 是一个 Java 库,用于创建临时 Docker 容器以进行单元测试。 当我们想避免使用实际服务器进行测试时,它很有用。
在本教程中,我们将学习如何在测试使用 Redis 的 Spring Boot 应用程序时使用 Testcontainers。
2. 项目设置
使用任何测试容器的第一个先决条件是在我们运行测试的机器上安装 Docker。
一旦我们安装了 Docker,我们就可以开始设置我们的 Spring Boot 应用程序了。
在这个应用程序中,我们将设置一个 Redis 哈希、一个存储库和一个将使用该存储库与 Redis 交互的服务。
2.1。 依赖项
让我们首先将所需的依赖项添加到我们的项目中。
首先,我们将添加Spring Boot Starter Test和Spring Boot Starter Data Redis依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
接下来,让我们添加Testcontainers依赖项:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.17.2</version>
<scope>test</scope>
</dependency>
2.2.自动配置
由于我们不需要任何高级配置,我们可以使用自动配置来建立与 Redis 服务器的连接。
为此,我们需要将 Redis 连接详细信息添加到文件中:application.properties
spring.redis.host=127.0.0.1
spring.redis.port=6379
3. 应用程序设置
让我们从主应用程序的代码开始。 我们将构建一个小型应用程序,用于将产品读取和写入 Redis 数据库。
3.1。 实体
让我们从类开始:Product
@RedisHash("product")
public class Product implements Serializable {
private String id;
private String name;
private double price;
// Constructor, getters and setters
}
@RedisHash
注解用于告诉 Spring Data Redis 这个类应该存储在 Redis 哈希中。 保存为哈希对于不包含嵌套对象的实体很有用。
3.2.存储库
接下来,我们可以为我们的哈希定义一个存储库:Product
@Repository
public interface ProductRepository extends CrudRepository<Product, String> {
}
CRUD 存储库接口已经实现了我们需要保存、更新、删除和查找产品的方法。 所以我们不需要自己定义任何方法。
3.3.服务
最后,让我们创建一个使用执行读写操作的服务:ProductRepository
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Product getProduct(String id) {
return productRepository.findById(id).orElse(null);
}
// other methods
}
然后,控制器或服务可以使用此服务对产品执行CRUD操作。
在实际应用中,这些方法可能包含更复杂的逻辑,但出于本教程的目的,我们将只关注 Redis 交互。
4. 测试
我们现在将为编写测试来测试CRUD操作。ProductService
4.1。 测试服务
让我们为ProductService:
@Test
void givenProductCreated_whenGettingProductById_thenProductExistsAndHasSameProperties() {
Product product = new Product("1", "Test Product", 10.0);
productService.createProduct(product);
Product productFromDb = productService.getProduct("1");
assertEquals("1", productFromDb.getId());
assertEquals("Test Product", productFromDb.getName());
assertEquals(10.0, productFromDb.getPrice());
}
这假定 Redis 数据库正在属性中指定的 URL 上运行。 如果我们没有运行 Redis 实例或者我们的服务器无法连接到它,测试将会出错。
4.2.使用 Testcontainers 启动 Redis 容器
让我们通过在运行测试时运行 Redis 测试容器来解决这个问题。 然后,我们将从代码本身更改连接详细信息。
让我们看一下创建和运行测试容器的代码:
static {
GenericContainer<?> redis =
new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")).withExposedPorts(6379);
redis.start();
}
让我们了解这段代码的不同部分:
我们从图像创建了一个新容器
redis:5.0.3-alpine
默认情况下,Redis 实例将在端口上运行。 要公开这个端口,我们可以使用方法。 它将公开此端口并将其映射到主机上的随机端口
6379
withExposedPorts()
start()
方法将启动容器并等待它准备好我们已将此代码添加到
static
代码块中,以便它在注入依赖项之前运行,并运行测试
4.3.更改连接详细信息
此时,我们有一个 Redis 容器正在运行,但我们没有更改应用程序使用的连接详细信息。 为此,我们需要做的就是使用系统属性覆盖application.properties
文件中的连接详细信息:
static {
GenericContainer<?> redis =
new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")).withExposedPorts(6379);
redis.start();
System.setProperty("spring.redis.host", redis.getHost());
System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString());
}
我们已经将spring.redis.host
属性设置为容器的 IP 地址。
我们可以获取端口6379
的映射端口来设置spring.redis.port
属性。
现在,当测试运行时,它们将连接到容器上运行的Redis数据库。
5.结论
在本文中,我们学习了如何使用 Redis Testcontainer 来运行测试。 我们还查看了 Spring Data Redis 的某些方面以了解如何使用它。
0 评论