Spring Boot – Testing Redis With Testcontainers – Spring Boot – 使用Testcontainers测试Redis

最后修改: 2022年 7月 14日

1. Overview


Testcontainers is a Java library for creating temporary Docker containers for unit testing purposes. It’s useful when we want to avoid testing with actual servers.


In this tutorial, we’ll learn how to use Testcontainers while testing a Spring Boot application that uses Redis.

在本教程中,我们将学习如何在测试使用Redis的Spring Boot应用程序时使用Testcontainers。

2. Project Setup


The first prerequisite to using any test container is to have Docker installed on the machine where we are running the tests.


Once we have Docker installed, we can start setting up our Spring Boot application.

一旦我们安装了Docker,我们就可以开始设置我们的Spring Boot应用程序。

In this application, we’ll set up a Redis hash, a repository, and a service that will use the repository to interact with Redis.


2.1. Dependencies

2.1. 依赖性

Let’s start by adding the required dependencies to our project.


Firstly, we’ll add the Spring Boot Starter Test and Spring Boot Starter Data Redis dependencies:

首先,我们将添加Spring Boot Starter TestSpring Boot Starter Data Redis依赖项。


Next, let’s add the Testcontainers dependency:



2.2. Autoconfiguration


Since we don’t require any advanced configurations, we can use autoconfiguration to set up a connection to the Redis server.


For this, we need to add the Redis connection details to the application.properties file:



3. Application Setup


Let’s start with the code for our main application. We’ll build a small application that reads and writes products to a Redis database.


3.1. Entity

3.1. 实体

Let’s start with the Product class:


public class Product implements Serializable {
    private String id;
    private String name;
    private double price;

    // Constructor,  getters and setters

The @RedisHash annotation is used to tell Spring Data Redis that this class should be stored in a Redis hash. Saving as a hash is good for entities that don’t contain nested objects.

@RedisHash注解用于告诉Spring Data Redis,该类应存储在Redis哈希中。以哈希形式保存对于不包含嵌套对象的实体来说是很好的。

3.2. Repository


Next, we can define a repository for our Product hash:


public interface ProductRepository extends CrudRepository<Product, String> {

The CRUD repository interface already implements the methods we need to save, update, delete and find products. So we don’t need to define any methods ourselves.


3.3. Service


Finally, let’s create a service that performs read and write operations using the ProductRepository:


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

This service can then be used by controllers or services to perform CRUD operations on the products.


In actual applications, these methods may contain more complex logic, but for the purposes of this tutorial, we’ll only focus on the Redis interactions.


4. Testing


We’ll now write tests for our ProductService to test the CRUD operations.


4.1. Testing the Service


Let’s write an integration test for the ProductService:


void givenProductCreated_whenGettingProductById_thenProductExistsAndHasSameProperties() {
    Product product = new Product("1", "Test Product", 10.0);
    Product productFromDb = productService.getProduct("1");
    assertEquals("1", productFromDb.getId());
    assertEquals("Test Product", productFromDb.getName());
    assertEquals(10.0, productFromDb.getPrice());

This assumes that a Redis database is running on the URL specified in the properties. If we don’t have a Redis instance running or our server cannot connect to it, the tests will run into errors.

这假定 Redis 数据库正在属性中指定的 URL 上运行。如果我们没有运行 Redis 实例,或者我们的服务器无法连接到它,测试将出现错误。

4.2. Starting a Redis Container With Testcontainers


Let’s solve this problem by running a Redis test container when the tests are run. Then, we’ll change the connection details from the code itself.


Let’s look at the code to create and run the test container:


static {
    GenericContainer<?> redis = 
      new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")).withExposedPorts(6379);

Let’s understand the different parts of this code:


  • we have created a new container from the image redis:5.0.3-alpine
  • by default, the Redis instance will run on port 6379. To expose this port, we can use the withExposedPorts() method. It’ll expose this port and map it to a random port on the host machine
  • the start() method will start the container and wait for it to be ready
  • we have added this code to a static code block so that it runs before the dependencies are injected, and tests are run

4.3. Changing the Connection Details


At this point, we have a Redis container running, but we haven’t changed the connection details used by the application. To do this, all we need to do is to override the connection details in the application.properties file using system properties:


static {
    GenericContainer<?> redis = 
      new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")).withExposedPorts(6379);
    System.setProperty("spring.redis.host", redis.getHost());
    System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString());

We’ve set the spring.redis.host property to the IP address of the container.

我们已经spring.redis.host属性设置为容器的 IP 地址。

We can get the mapped port of port 6379 to set the spring.redis.port property.


Now when the tests run, they’ll connect to the Redis database running on the container.


5. Conclusion


In this article, we learned how to use Redis Testcontainer to run the tests. We also looked at certain aspects of Spring Data Redis to understand how to use it.

在这篇文章中,我们学习了如何使用Redis Testcontainer来运行测试。我们还研究了Spring Data Redis的某些方面,以了解如何使用它。

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