redis单元测试

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里面有单元测试:http://git.snowballfinance.com/lib/redis-cluster4


 

RedisCluster4使用步骤:

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

<dependency>
 <groupId>com.xueqiu.infra</groupId>
 <artifactId>test-tools</artifactId>
 <version>1.0.3</version>
</dependency>

version版本根据实时情况更新

redis cluster 4使用示例:

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

示例地址:

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

/**
 * RedisCluster 4 unit test
 *
 * redis 4.X集群的单元测试,同时是为了兼容雪球的redis SDK(RedisCluster至于名字是历史问题向下兼容造成的)
 */
@Test
public void testRedisCluster4(){
    TestEnvironment env = new TestEnvironmentBuilder()
            .withRedisCluster4(3)
            .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

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

--RateLimitClientTest.java

BaseTestConfig.java 

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 

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

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());
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值