Rust Redis测试插件库redis-test的使用,高效实现Redis连接与操作的功能测试

Rust Redis测试插件库redis-test的使用,高效实现Redis连接与操作的功能测试

redis-test是为redis-rs crate提供的测试工具库。

安装

在项目目录中运行以下Cargo命令:

cargo add redis-test

或者在Cargo.toml中添加以下行:

redis-test = "0.11.0"

使用示例

下面是一个完整的示例,展示如何使用redis-test进行Redis连接和操作的功能测试:

use redis::Commands;
use redis_test::{RedisTest, RedisTestServer};

#[test]
fn test_redis_operations() {
    // 启动Redis测试服务器
    let server = RedisTestServer::new().unwrap();
    let client = server.client();
    
    // 获取Redis连接
    let mut con = client.get_connection().unwrap();
    
    // 测试基本操作
    let _: () = con.set("test_key", "test_value").unwrap();
    let value: String = con.get("test_key").unwrap();
    assert_eq!(value, "test_value");
    
    // 测试哈希操作
    let _: () = con.hset("test_hash", "field1", "value1").unwrap();
    let hash_value: String = con.hget("test_hash", "field1").unwrap();
    assert_eq!(hash_value, "value1");
    
    // 测试列表操作
    let _: () = con.rpush("test_list", "item1").unwrap();
    let _: () = con.rpush("test_list", "item2").unwrap();
    let list_len: i64 = con.llen("test_list").unwrap();
    assert_eq!(list_len, 2);
    
    // 测试设置操作
    let _: () = con.sadd("test_set", "member1").unwrap();
    let is_member: bool = con.sismember("test_set", "member1").unwrap();
    assert!(is_member);
}

完整示例demo

下面是一个更完整的测试示例,展示更多Redis操作类型:

use redis::{Commands, RedisResult};
use redis_test::{RedisTest, RedisTestServer};

#[test]
fn test_redis_comprehensive() {
    // 启动测试Redis服务器
 let server = RedisTestServer::new().unwrap();
 let client = server.client();
 
 // 获取连接
 let mut conn = client.get_connection().unwrap();
 
 // 1. 测试字符串操作
 test_string_operations(&mut conn).unwrap();
 
 // 2. 测试哈希操作
 test_hash_operations(&mut conn).unwrap();
 
 // 3. 测试列表操作
 test_list_operations(&mut conn).unwrap();
 
 // 4. 测试集合操作
 test_set_operations(&mut conn).unwrap();
 
 // 5. 测试有序集合操作
 test_zset_operations(&mut conn).unwrap();
 
 // 6. 测试键操作
 test_key_operations(&mut conn).unwrap();
}

fn test_string_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 // 设置键值
 conn.set("str_key", "hello")?;
 
 // 获取值
 let value: String = conn.get("str_key")?;
 assert_eq!(value, "hello");
 
 // 设置过期时间
 conn.set_ex("exp_key", "world", 10)?;
 
 Ok(())
}

fn test_hash_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 // 设置哈希字段
 conn.hset_multiple("user:1", &[("name", "Alice"), ("age", "30")])?;
 
 // 获取单个字段
 let name: String = conn.hget("user:1", "name")?;
 assert_eq!(name, "Alice");
 
 // 获取所有字段
 let user: Vec<(String, String)> = conn.hgetall("user:1")?;
 assert_eq!(user.len(), 2);
 
 Ok(())
}

fn test_list_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 // 从右侧推入元素
 conn.rpush("mylist", "one")?;
 conn.rpush("mylist", "two")?;
 
 // 获取列表长度
 let len: i64 = conn.llen("mylist")?;
 assert_eq!(len, 2);
 
 // 获取范围元素
 let items: Vec<String> = conn.lrange("mylist", 0, -1)?;
 assert_eq!(items, vec!["one", "two"]);
 
 Ok(())
}

fn test_set_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 // 添加集合成员
 conn.sadd("myset", "a")?;
 conn.sadd("myset", "b")?;
 
 // 检查成员是否存在
 let exists: bool = conn.sismember("myset", "a")?;
 assert!(exists);
 
 // 获取所有成员
 let members: Vec<String> = conn.smembers("myset")?;
 assert_eq!(members.len(), 2);
 
 Ok(())
}

fn test_zset_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 // 添加有序集合成员
 conn.zadd("zset", "member1", 1)?;
 conn.zadd("zset", "member2", 2)?;
 
 // 获取成员分数
 let score: i64 = conn.zscore("zset", "member1")?;
 assert_eq!(score, 1);
 
 Ok(())
}

fn test_key_operations(conn: &mut redis::Connection) -> RedisResult<()> {
 conn.set("temp_key", "value")?;
 
 // 检查键是否存在
 let exists: bool = conn.exists("temp_key")?;
 assert!(exists);
 
 // 删除键
 conn.del("temp_key")?;
 
 Ok(())
}

主要功能

  1. RedisTestServer - 提供嵌入式Redis服务器用于测试
  2. 自动清理 - 测试完成后自动清理Redis数据
  3. 隔离测试 - 每个测试运行在独立的Redis实例中
  4. 真实连接 - 使用真实的Redis连接进行测试

应用场景

  • 单元测试Redis操作
  • 集成测试Redis相关功能
  • 验证Redis命令的正确性
  • 测试Redis连接池

这个库特别适合需要在测试中使用Redis但不想依赖外部Redis服务器的场景。


1 回复

Rust Redis测试插件库redis-test的使用指南

介绍

redis-test是一个专为Rust设计的Redis测试插件库,它简化了在Rust项目中与Redis交互的功能测试流程。该库提供了简洁的API来建立Redis连接、执行操作以及清理测试环境,特别适合在单元测试和集成测试场景中使用。

主要特性

  • 轻量级Redis连接管理
  • 自动清理测试数据
  • 支持同步和异步操作
  • 内置常用Redis命令的便捷方法
  • 测试友好的设计

安装

在Cargo.toml中添加依赖:

[dependencies]
redis-test = "0.1"
redis = "0.22"  # 基础redis库

基本使用方法

1. 同步测试示例

use redis_test::{RedisTest, RedisTestError};

#[test]
fn test_basic_operations() -> Result<(), RedisTestError> {
    // 创建测试实例
    let redis = RedisTest::new()?;
    
    // 设置键值
    redis.set("test_key", "test_value")?;
    
    // 获取值
    let value: String = redis.get("test_key")?;
    assert_eq(value, "test_value");
    
    // 测试完成后自动清理
    Ok(())
}

2. 异步测试示例

use redis_test::{AsyncRedisTest, RedisTestError};

#[tokio::test]
async fn test_async_operations() -> Result<(), RedisTestError> {
    // 创建异步测试实例
    let redis = AsyncRedisTest::new().await?;
    
    // 异步设置键值
    redis.set_async("async_key", "async_value").await?;
    
    // 异步获取值
    let value: String = redis.get_async("async_key").await?;
    assert_eq(value, "async_value");
    
    Ok(())
}

高级用法

自定义Redis连接配置

use redis_test::{RedisTest, RedisTestConfig};

let config = RedisTestConfig {
    host: "127.0.0.1".to_string(),
    port: 6379,
    db: 1,  // 使用特定数据库
    ..Default::default()
};

let redis = RedisTest::with_config(config)?;

测试事务操作

#[test]
fn test_transaction() -> Result<(), RedisTestError> {
    let redis = RedisTest::new()?;
    
    let (value1, value2): (i32, i32) = redis.transaction(|pipe| {
        pipe.set("tx_key1", 42)
            .ignore()
            .set("tx_key2", 24)
            .ignore()
            .get("tx_key1")
            .get("tx_key2")
    })?;
    
    assert_eq(value1, 42);
    assert_eq(value2, 24);
    
    Ok(())
}

测试哈希操作

#[test]
fn test_hash_operations() -> Result<(), RedisTestError> {
    let redis = RedisTest::new()?;
    
    // 设置哈希字段
    redis.hset("user:1", "name", "Alice")?;
    redis.hset("user:1", "age", 30)?;
    
    // 获取哈希字段
    let name: String = redis.hget("user:1", "name")?;
    let age: i32 = redis.hget("user:1", "age")?;
    
    assert_eq(name, "Alice");
    assert_eq(age, 30);
    
    Ok(())
}

完整示例代码

下面是一个完整的测试模块示例,展示了如何使用redis-test进行多种Redis操作测试:

use redis_test::{RedisTest, AsyncRedisTest, RedisTestError, RedisTestConfig};

// 同步测试模块
mod sync_tests {
    use super::*;
    
    #[test]
    fn test_string_operations() -> Result<(), RedisTestError> {
        // 创建测试实例
        let redis = RedisTest::new()?;
        
        // 测试SET/GET命令
        redis.set("my_string", "hello")?;
        let value: String = redis.get("my_string")?;
        assert_eq!(value, "hello");
        
        Ok(())
    }
    
    #[test]
    fn test_list_operations() -> Result<(), RedisTestError> {
        let redis = RedisTest::new()?;
        
        // 测试列表操作
        redis.lpush("my_list", "item1")?;
        redis.lpush("my_list", "item2")?;
        
        let len: i64 = redis.llen("my_list")?;
        assert_eq!(len, 2);
        
        let item: String = redis.lpop("my_list")?;
        assert_eq!(item, "item2");
        
        Ok(())
    }
}

// 异步测试模块
mod async_tests {
    use super::*;
    
    #[tokio::test]
    async fn test_async_set_get() -> Result<(), RedisTestError> {
        let redis = AsyncRedisTest::new().await?;
        
        // 异步设置和获取
        redis.set_async("async_key", 42).await?;
        let value: i32 = redis.get_async("async_key").await?;
        assert_eq!(value, 42);
        
        Ok(())
    }
}

// 使用自定义配置的测试
#[test]
fn test_with_custom_config() -> Result<(), RedisTestError> {
    let config = RedisTestConfig {
        host: "127.0.0.1".to_string(),
        port: 6379,
        db: 2, // 使用数据库2
        prefix: "custom:".to_string(), // 自定义键前缀
        ..Default::default()
    };
    
    let redis = RedisTest::with_config(config)?;
    
    redis.set("config_test", "works")?;
    let value: String = redis.get("config_test")?;
    assert_eq!(value, "works");
    
    Ok(())
}

// 测试事务和哈希组合操作
#[test]
fn test_transaction_with_hash() -> Result<(), RedisTestError> {
    let redis = RedisTest::new()?;
    
    let (name, age): (String, i32) = redis.transaction(|pipe| {
        pipe.hset("user:100", "name", "Bob")
            .ignore()
            .hset("user:100", "age", 35)
            .ignore()
            .hget("user:100", "name")
            .hget("user:100", "age")
    })?;
    
    assert_eq!(name, "Bob");
    assert_eq!(age, 35);
    
    Ok(())
}

清理策略

redis-test默认会在测试完成后自动清理所有创建的键。你也可以自定义清理行为:

let redis = RedisTest::new()
    .auto_clean(false)  // 禁用自动清理
    .prefix("my_test:") // 设置键前缀
    .build()?;

// 手动清理
redis.clean()?;

最佳实践

  1. 为不同的测试模块使用不同的Redis数据库或键前缀
  2. 在测试前确保Redis服务可用
  3. 对于长时间运行的测试,考虑禁用自动清理以检查测试数据
  4. 在CI环境中使用专门的测试Redis实例

注意事项

  • 该库假设Redis服务器运行在本地默认端口(6379)
  • 测试键默认以"test:"作为前缀,可通过配置修改
  • 确保测试环境中的Redis服务器版本支持所使用的命令

通过redis-test库,你可以更高效地编写与Redis相关的功能测试,而无需担心测试数据的污染和清理问题。

回到顶部