测试转移函数

⚠️ Update Notice:

Please read Substrate to Polkadot SDK page first.


测试每个函数是为生产环境开发 pallet 的重要部分。 本指南逐步介绍了为基本 transfer 函数编写测试用例的最佳实践。

概述 transfer 函数

转移函数有两个关键要素:从一个帐户中减去余额并将该余额添加到另一个帐户。 在这里,我们将首先概述此函数:

#[pallet::weight(10_000)]
pub (super) fn transfer(
  origin: OriginFor<T>,
  to: T::AccountId,
  #[pallet::compact] amount: T::Balance,
  ) -> DispatchResultWithPostInfo {
    let sender = ensure_signed(origin)?;

    Accounts::<T>::mutate(&sender, |bal| {
      *bal = bal.saturating_sub(amount);
      });
      Accounts::<T>::mutate(&to, |bal| {
        *bal = bal.saturating_add(amount);
        });

    Self::deposit_event(Event::<T>::Transferred(sender, to, amount))
    Ok(().into())
}

检查发送者是否有足够的余额

首先要验证的是发送者是否有足够的余额。 在单独的 tests.rs 文件中,编写此第一个测试用例:

#[test]
fn transfer_works() {
  new_test_ext().execute_with(|| {
    MetaDataStore::<Test>::put(MetaData {
			issuance: 0,
			minter: 1,
			burner: 1,
		});
    // 向帐户 2 铸造 42 个代币。
    assert_ok!(RewardCoin::mint(RuntimeOrigin::signed(1), 2, 42));
    // 向帐户 3 发送 50 个代币。
    asset_noop!(RewardCoin::transfer(RuntimeOrigin::signed(2), 3, 50), Error::<T>::InsufficientBalance);

配置错误处理

要实现一些错误检查,请将 mutate 替换为 try_mutate 以使用 ensure!。 这将检查bal 是否大于或等于 amount,如果否,则会抛出错误消息:

Accounts::<T>::try_mutate(&sender, |bal| {
  ensure!(bal >= amount, Error::<T>::InsufficientBalance);
  *bal = bal.saturating_sub(amount);
  Ok(())
});

从您的 pallet 目录运行 cargo test

检查发送帐户是否未低于最低余额

在您的 transfer_works 函数中:

assert_noop!(RewardCoin::transfer(RuntimeOrigin::signed(2), 3, 50), Error::<Test>::InsufficientBalance);

检查两个测试是否一起工作

使用 #[transactional] 为两个检查生成一个包装器:

#[transactional]
pub(super) fn transfer(
/*--snip--*/

处理尘埃帐户

确保发送和接收帐户不是尘埃帐户。使用 T::MinBalance::get()

/*--snip--*/
let new_bal = bal.checked_sub(&amount).ok_or(Error::<T>::InsufficientBalance)?;
ensure!(new_bal >= T::MinBalance::get(), Error::<T>::BelowMinBalance);
/*--snip--*/

示例

资源