redis单元测试

283 阅读2分钟

embedded-redis:Redis embedded server for Java integration testing

redis-unit:Redis instance for unit testing applications.

原理:

启动java的嵌入式redis,然后获取启动时的随机端口,通过spring-redis的创建工厂映射自己需要的bean(使用雪球RedisCluster4的,redis-sdk里面有单元测试:git.snowballfinance.com/lib/redis-c…


 

RedisCluster4使用步骤:

test-tools项目已经封装了对redis cluster 4的依赖和默认设置,故只需引入pom即可

| ```html com.xueqiu.infra test-tools 1.0.3

| ------------------------------------------------------------------------------------------------------------------------------------------ |

version版本根据实时情况更新

redis cluster 4使用示例:

只需指定你要启动的节点数(示例中启动了三个节点),详情见如下示例地址

示例地址:

源码版:<http://git.snowballfinance.com/lib/test-tools>

| ```html
/**  * RedisCluster 4 unit test  *  * redis 4.X集群的单元测试,同时是为了兼容雪球的redis SDK(RedisCluster至于名字是历史问题向下兼容造成的)  */ @Test public void testRedisCluster4(){     TestEnvironment env = new TestEnvironmentBuilder()             .withRedisCluster4(3)
``````html
            .build();  try {         RedisCluster4 redisCluster4 = env.redisCluster4().get();  List<RedisClusterConfig> clusterConfigs = redisCluster4.getRedisClusterConfigList();  System.out.println(clusterConfigs);  String connectString = redisCluster4.getConnectionStringList().stream().collect(Collectors.joining(","));  com.xueqiu.infra.redis4.RedisCluster redisClient = RedisClusterImpl.create(connectString, 4, MetricsFactory.create("RedisClusterImplUnitTest"));  redisClient.set("k1", "v1");  System.out.println(redisClient.get("k1"));  Assert.assertEquals("v1", redisClient.get("k1"));  } catch (Exception e) {         Assert.assertTrue(false);  throw new RuntimeException("redis cluster 4 test error.", e);  } }
``` |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

 

示例地址:

spring版:[http://git.snowballfinance.com/hekuangsheng/xueqiu-push](http://git.snowballfinance.com/lib/xueqiu-push)

| `test的resource目录下添加sql文件` `src` `  ``--main` `    ``--test` `      ``--java` `        ``--包路径` `          ``--TestConfig.java` `          ``--BaseTests.java` `          ``--limit``--RateLimitClientTest.java` |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

BaseTestConfig.java 

| ```html
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.xueqiu.infra.test.tools.TestEnvironment; import com.xueqiu.infra.test.tools.TestEnvironmentBuilder; import com.xueqiu.infra.test.tools.entity.RedisCluster4; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager;  import javax.sql.DataSource; import java.util.Arrays; import java.util.List;  @Configuration @AutoConfigureOrder(0) public class BaseTestConfig {      private TestEnvironment env = new TestEnvironmentBuilder()             .withH2Database(Arrays.asList("sql/demo_schema.sql", "sql/demo_data.sql"))             .withRedisCluster4(4)             .build();      @Bean     public DataSource dataSource() {         return TestEnvironment.jdbcDataSource()                 .orElseThrow(() -> new RuntimeException("init test data source fail"));     }      @Bean(name = "xueqiupushTemplate")     public JdbcTemplate jdbcTemplate() {         return new JdbcTemplate(dataSource());     }      @Bean     public PlatformTransactionManager transactionManager(DataSource dataSource) {         DataSourceTransactionManager tm = new DataSourceTransactionManager();         tm.setDataSource(dataSource);         return tm;     }      @Bean     public RedisConnectionFactory factory(){         RedisCluster4 redisCluster4 = TestEnvironment.redisCluster4()                 .orElseThrow(() -> new RuntimeException("init test redis cluster fail"));         List<String> connectionStringList = redisCluster4.getConnectionStringList();         RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(connectionStringList);         RedisConnectionFactory connectionFactory = new LettuceConnectionFactory(redisClusterConfiguration);         return connectionFactory;     }      @Bean     public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {         StringRedisTemplate template = new StringRedisTemplate(factory);         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);         ObjectMapper om = new ObjectMapper();         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);         om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);         jackson2JsonRedisSerializer.setObjectMapper(om);         template.setValueSerializer(jackson2JsonRedisSerializer);         template.afterPropertiesSet();         return template;     }      @Bean("rateLimitLua")     public DefaultRedisScript getRedisScript() {         DefaultRedisScript redisScript = new DefaultRedisScript();         redisScript.setLocation(new ClassPathResource("limit/ratelimit.lua"));         redisScript.setResultType(java.util.List.class);         return redisScript;     }      @Bean("rateLimitInitLua")     public DefaultRedisScript getInitRedisScript() {         DefaultRedisScript redisScript = new DefaultRedisScript();         redisScript.setLocation(new ClassPathResource("limit/ratelimitInit.lua"));         redisScript.setResultType(Long.class);         return redisScript;     } }
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

BaseJunit4Test.java 

| ```html
import org.junit.Ignore; import org.junit.runner.RunWith; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Controller; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.transaction.annotation.Transactional;  @Ignore @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = BaseTestConfig.class) @TestExecutionListeners(TransactionalTestExecutionListener.class) @Transactional @ComponentScan(         basePackages = {                 "com.xueqiu.infra.push.server.entity",                 "com.xueqiu.infra.push.server.limit",         },         excludeFilters = {                 @ComponentScan.Filter(Controller.class)         } ) public class BaseJunit4Test extends AbstractJUnit4SpringContextTests {  }
``` |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

RateLimitClientTest.java

| ```html
import com.xueqiu.infra.push.server.BaseJunit4Test; import org.junit.Test; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.RedisScript;  import javax.annotation.Resource; import java.util.Collections; import java.util.List;  import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue;  public class RateLimitClientTest extends BaseJunit4Test {      private static final String UNIT_TEST_KEY = "UNIT_TEST_KEY";     private final static long PERMITS_PER_SECOND = 3250;      @Resource     private StringRedisTemplate stringRedisTemplate;     @Resource(name = "rateLimitLua")     private RedisScript<List> rateLimitLua;     @Resource(name = "rateLimitInitLua")     private RedisScript<Long> rateLimitInitLua;      RateLimitClient rateLimitClient = new RateLimitClient();      @Test     public void initToken_and_acquireIntervalAndToken_test() {         Long acquire = stringRedisTemplate.execute(rateLimitInitLua,                 Collections.singletonList(rateLimitClient.getKey(UNIT_TEST_KEY)), String.valueOf(PERMITS_PER_SECOND), String.valueOf(PERMITS_PER_SECOND));         assertEquals(Long.valueOf(1L), acquire);          boolean result = stringRedisTemplate.hasKey(rateLimitClient.getKey(UNIT_TEST_KEY));         assertTrue(result);          List<Object> objectList = stringRedisTemplate.opsForHash().values(rateLimitClient.getKey(UNIT_TEST_KEY));         assertEquals(3, objectList.size());     } }
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |