如何编写单元测试验证NEAR合约转账是否成功
NEAR 合约转账逻辑的单元测试编写方案
针对提供的、用于向b.testnet账户转移用户附着存款的合约逻辑,可以依托near-sdk内置的沙箱测试能力完成全流程正确性校验,测试全程不需要连接真实链网,具体实现步骤如下:
测试前置依赖引入
需要在测试模块中引入near-sdk提供的测试工具集,无需额外搭建外部测试环境:
#[cfg(test)] mod transfer_tests { use near_sdk::{testing_env, test_utils::{VMContextBuilder, get_account_balance}}; use near_sdk::{AccountId, Promise}; use std::str::FromStr; }
初始化模拟链环境
在测试用例中先构造符合合约执行要求的模拟上下文,提前配置可复现的测试参数:
- 待测试合约的部署账户ID
- 模拟交易发起方的身份
- 自定义测试用的附着存款金额(比如取1 NEAR 即
1_000_000_000_000_000_000_000_000yoctoNEAR作为测试值) - 提前记录目标账户
b.testnet的初始链上余额,用于后续的到账校验
示例初始化代码:
#[test] fn test_attached_deposit_transfer() { // 初始化测试目标账户 let target_account = AccountId::from_str("b.testnet").unwrap(); // 记录目标账户的初始链上余额 let initial_target_balance = get_account_balance(&target_account).0; // 构造模拟交易执行上下文 let mock_context = VMContextBuilder::new() .current_account_id(AccountId::from_str("contract.testnet").unwrap()) // 部署待测试合约的账户 .attached_deposit(1_000_000_000_000_000_000_000_000) // 模拟用户发起交易时附带的1 NEAR存款 .build(); testing_env!(mock_context); }
执行待测试逻辑并完成核心校验
模拟调用合约的转账方法后,通过沙箱提供的可观测接口,从三个维度完成正确性校验:
- 校验构造的Promise指向正确的目标账户,没有出现硬编码错误
- 校验Promise携带的转账金额和用户传入的附着存款值完全一致,没有出现金额计算错误
- 模拟链上完成Promise执行的入账流程后,校验目标账户的余额增量和转出金额完全匹配
示例校验代码:
// 执行待测试的转账逻辑,等价于你提供的合约方法实现 Promise::new(target_account.clone()) .transfer(near_sdk::env::attached_deposit()); // 从沙箱中取出最近一次构造的Promise元数据 let recorded_promise = near_sdk::env::test_utils::get_last_promise(); // 第一重断言:确认转账目标没有配置错误 assert_eq!( recorded_promise.account_id, target_account, "转账目标账户错误,未指向b.testnet" ); // 第二重断言:确认转账金额和用户附着存款完全匹配 let expected_transfer_amount = near_sdk::env::attached_deposit(); assert_eq!( recorded_promise.amount, expected_transfer_amount, "转账金额和用户传入的附着存款值不匹配" ); // 手动模拟链上执行该Promise,完成实际的资金划转 near_sdk::env::test_utils::finish_promise( 0, // 已生成Promise的索引,测试中我们只构造了1个Promise near_primitives::views::FinalExecutionStatus::SuccessValue(Vec::new()) ); // 第三重断言:确认目标账户正确收到转账资金 let current_target_balance = get_account_balance(&target_account).0; assert_eq!( current_target_balance - initial_target_balance, expected_transfer_amount, "目标账户未正确收到转账资金" );
注意:near-sdk默认的沙箱测试不会自动执行合约生成的跨账户Promise,必须手动调用
finish_promise接口模拟链上的交易执行流程,才能完成真实的余额流转校验。如果不触发这一步,测试只能验证合约是否正确构造了转账请求,无法验证最终的资金到账结果。
内容的提问来源于stack exchange,提问作者Peter Salomonsen
相关产品推荐
相关产品推荐

