You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AWS Rust Lambda Runtime与AWS Rust SDK的应用测试与Mock方案问询

Rust AWS Lambda + DynamoDB:离线测试与Mock AWS SDK指南

一、单元测试:直接Mock AWS SDK调用

AWS Rust SDK(如aws-sdk-dynamodb)本身提供了测试工具链,无需额外第三方库即可Mock服务调用。核心思路是通过自定义的Connector替换真实服务连接,返回预设响应。

示例代码(Mock DynamoDB GetItem操作):

use aws_sdk_dynamodb::{Client, Error, types::AttributeValue};
use aws_smithy_runtime::client::test_util::capture_requests;

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_dynamodb_get_item() -> Result<(), Error> {
        // 创建Mock客户端,捕获请求并返回预设响应
        let (client, _request_recorder) = capture_requests(|req| {
            match req.operation_name() {
                "GetItem" => {
                    let response = aws_sdk_dynamodb::operation::get_item::builders::GetItemOutputBuilder::default()
                        .item("Id", AttributeValue::S("123".to_string()))
                        .build()
                        .unwrap();
                    Ok(response)
                }
                op => panic!("Unexpected operation: {}", op),
            }
        });

        // 使用Mock客户端执行测试
        let resp = client.get_item()
            .table_name("test-table")
            .key("Id", AttributeValue::S("123".to_string()))
            .send()
            .await?;

        assert_eq!(resp.item().unwrap().get("Id").unwrap().as_s().unwrap(), "123");
        Ok(())
    }
}

二、离线手动测试:Cargo Lambda配合本地Mock服务

Cargo Lambda的watch命令仅负责热重载Lambda函数,本身不提供AWS服务Mock能力,需搭配本地AWS服务模拟器使用,推荐DynamoDB Local或LocalStack:

步骤1:启动本地Mock服务

以DynamoDB Local为例,用Docker启动:

docker run -p 8000:8000 amazon/dynamodb-local

步骤2:配置Cargo Lambda指向本地服务

运行Cargo Lambda时指定环境变量,让AWS SDK将请求发向本地模拟器:

AWS_ENDPOINT_URL=http://localhost:8000 AWS_REGION=us-east-1 cargo lambda watch

也可在项目根目录创建.env文件持久化配置:

AWS_ENDPOINT_URL=http://localhost:8000
AWS_REGION=us-east-1

步骤3:初始化本地测试资源

用AWS CLI连接本地服务创建测试表:

aws dynamodb create-table \
  --table-name test-table \
  --attribute-definitions AttributeName=Id,AttributeType=S \
  --key-schema AttributeName=Id,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
  --endpoint-url http://localhost:8000

三、进阶:解耦业务与SDK,用Trait Mock

若需更灵活的Mock逻辑,可将DynamoDB操作抽象为Trait,通过mockall框架Mock该Trait,实现业务逻辑与SDK的解耦:

use aws_sdk_dynamodb::Client;
use aws_sdk_dynamodb::types::AttributeValue;
use aws_sdk_dynamodb::Error;

// 定义抽象Trait
trait DynamoDbOps {
    async fn get_item(&self, table_name: &str, id: &str) -> Result<Option<AttributeValue>, Error>;
}

// 真实服务实现
struct RealDynamoDb {
    client: Client,
}

impl DynamoDbOps for RealDynamoDb {
    async fn get_item(&self, table_name: &str, id: &str) -> Result<Option<AttributeValue>, Error> {
        let resp = self.client.get_item()
            .table_name(table_name)
            .key("Id", AttributeValue::S(id.to_string()))
            .send()
            .await?;
        Ok(resp.item().and_then(|item| item.get("Id").cloned()))
    }
}

// 单元测试用Mock
#[cfg(test)]
mod tests {
    use super::*;
    use mockall::mock;

    mock! {
        pub DynamoDbOps {}
        impl DynamoDbOps for DynamoDbOps {
            async fn get_item(&self, table_name: &str, id: &str) -> Result<Option<AttributeValue>, Error>;
        }
    }

    #[tokio::test]
    async fn test_lambda_handler() {
        let mut mock_db = MockDynamoDbOps::new();
        mock_db.expect_get_item()
            .withf(|table, id| table == "test-table" && id == "123")
            .returning(|_, _| Ok(Some(AttributeValue::S("123".to_string()))));

        // 将Mock实例传入Lambda handler执行测试
        let result = handler(mock_db).await;
        assert!(result.is_ok());
    }
}

内容的提问来源于stack exchange,提问作者Charlie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:10:32