作为Key-Value型的内存数据库,redis已经是Spring开发的标配。在单元测试/集成测试时,如果有一个带有redis服务的独享环境,对于保障测试用例执行的可靠性来说还是有所帮助的,也免除了很多由于环境冲突所导致的问题。当然,嵌入式redis主要还是完成数据的读写等基础的功能,如果涉及到高可用/同步等redis的高级特性,还是建议采用同生产上使用的redis。
嵌入式redis
基本上最Popular的嵌入式redis是以下这个项目 https://github.com/kstyrc/embedded-redis
但这个项目也存在维护不力的问题。 1) 大量缺陷未修复。在笔者写下此文时,这个项目上未关闭的缺陷issues 有33个。并且CI 显示目前这个版本在windows上的构建是失败的。
经过试用之后,笔者发现,以下这个案例能够顺利通过。
package redis.embedded;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import static org.junit.Assert.assertEquals;
public class RedisServerClusterTest {
private RedisServer redisServer1;
private RedisServer redisServer2;
@Before
public void setUp() throws Exception {
redisServer1 = RedisServer.builder()
.port()
.build();
redisServer2 = RedisServer.builder()
.port()
.slaveOf("localhost", )
.build();
redisServer1.start();
redisServer2.start();
}
@Test
public void testSimpleOperationsAfterRun() throws Exception {
JedisPool pool = null;
Jedis jedis = null;
try {
pool = new JedisPool("localhost", );
jedis = pool.getResource();
jedis.mset("abc", "1", "def", "2");
assertEquals("1", jedis.mget("abc").get());
assertEquals("2", jedis.mget("def").get());
assertEquals(null, jedis.mget("xyz").get());
} finally {
if (jedis != null)
pool.returnResource(jedis);
}
}
@After
public void tearDown() throws Exception {
redisServer1.stop();
redisServer2.stop();
}
}
但是在用例执行完之后, 程序似乎留下了一些未关闭的进程,可能会导致资源泄露和可能的端口冲突。因此,可能需要去优化redisServer的stop方法,或者干脆通过在@After方法中手工去杀进程的方式将运行环境清理干净。

redis_firewall.JPG

redis_process_detail.JPG

redis_process_list.JPG
无论如何,这个redis实现也算是解决了从0到1的问题,能接受这些问题的话,就勉强用用吧 。