繁体   English   中英

使用Redis进行集成测试

[英]Integration Testing with Redis

我在Jedis库的帮助下开始在我的项目中使用Redis。 一切正常,但现在我遇到了一个问题,我的功能测试要求Redis在我的持续集成中要避免。 做这个的最好方式是什么?

我为Java实现了一个简单的redis嵌入式运行器: https//github.com/kstyrc/embedded-redis

目前,它使用redis 2.6.14 for * nix和https://github.com/MSOpenTech/redis for Windows。 但是,您可以使用RedisServer类来运行自己的运行脚本。

我计划扩展实现以支持RedisConf(bind,slaveof,port,dbfilename等)。 在此之后,我会将jar上传到clojars for mvn deps。

以下是功能/集成测试的几个选项:

  1. 只需在CI服务器上启动redis实例。 所有测试都将负责在执行后进行适当的清理。
  2. 尝试以某种方式控制redis进程,即在CI服务器上有一些shell脚本或作业,以在运行测试之前/之后启动/停止它。 至少一些设置/清理的负担从测试中删除,因为对于每个独立的构建,您将具有独立的redis设置。
  3. 通过使用一些内存解决方案进一步控制redis,就像你提到的cassandra(如果它存在的话)。

有一点需要提及的是,集成测试不应取代单元测试。 单元测试应该是首选,它们可以涵盖更多情况,而集成测试可以用于检查应用程序的所有部分是否可以很好地协同工作。 而且我认为这就是为什么很多人选择选择第一选项的原因。

这是一个关于mongodb的类似问题答案有一个链接到项目,它适用于第二个选项(控制mongodb进程)如果你在项目页面上关注一些相关的链接,那么还有一个叫做nosql-unit的东西。 我认为这个试图涵盖选项三。 我没有使用它,但看起来它也有redis的东西。

您可以通过命令行在任意端口上启动Redis服务器: redis-server --port 7777 因此,出于集成测试的目的,您可以在可用(或随机)端口上启动Redis,确保将Jedis配置为使用该端口。

通过这种方式,您可以获得Redis的“新鲜”实例,您知道它不会与任何其他进程冲突,包括同时发生的其他测试运行。 这与我能想到的运行内存/嵌入式数据库进行集成测试的模拟结果非常接近。

要使用“预制数据”预加载Redis,请使用--dbfilename <file>开关: redis-server --port 7777 --dbfilename test.rdb

试试nosql-unit 它支持使用java进行redis单元测试。

我尝试过EmbeddedRedis,发现很多Jedis接口都不受支持。 因此使用EmbbededRedis不是一个好主意,特别是当你使用一些高级redis函数,如“管道”。

我建议使用ManagedRedis进行单元测试:

  1. redis.io下载redis源代码到您的测试资源中
  2. 在$(your-redis-dir)/ src中构建一个redis-server
  3. 用ManagedRedis编写单元测试,这是一个例子 请注意,“REDIS_HOME”是您的redis代码下载的目录,ManagedRedis将在$ {REDIS_HOME} / src中找到redis-server
  4. 运行单元测试。

正如@ksytrc在他的回答中提到的,我基本上使用了他的解决方案。 它正在这个项目中工作。你只需要添加embedded-redis依赖项。

        <dependency>
            <groupId>com.github.kstyrc</groupId>
            <artifactId>embedded-redis</artifactId>
            <version>0.6</version>
            <scope>test</scope>
        </dependency>

然后在测试类中定义redisServer

RedisServer redisServer;

    @Before
    public void setUp() throws IOException {
        redisServer = new RedisServer();
        redisServer.start();
    }

还使用以下凭据定义application.yml

spring:
  redis:
    host: localhost
    port: 6379

我能够处理同样问题的更好方法是创建一个处理RedisTemplate的Spring服务。 之后,我只使用@MockBean来模拟服务并抽象出我在测试期间运行的Redis实例的缺失。

每个例子:

@Service
class RedisService {

    @Autowired
    private RedisTemplate<String, SomeClass> redisTemplate;

    SomeClass get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

}

并在集成测试中:

class IntegrationTest {

    @MockBean
    private RedisService redisService;

    @Before
    public void setup() {
        SomeClass someClass= new SomeClass();
        when(redisService.get(anyString())).thenReturn(someClass);
    }


}

我对使用一些redis内存数据库解决方案持怀疑态度,因为我知道实际的替代方案并非由Spring团队“正式”推荐。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM