如何在Foundry测试中,转账调用合约函数并断言属性变更?
解决Foundry中同时验证转账与合约变量修改的问题
核心问题是你之前用_investorWallet.call{value: investmentAmount}(...)的方式,没有正确调用到receiveInvestment()函数——如果call的参数里没带函数签名,只会触发合约的fallback/receive回调,而非目标函数,所以变量修改逻辑没执行。
正确的做法是用Foundry的vm.prank()切换调用者身份,再直接调用合约的payable函数,这样就能同时实现指定钱包转账、执行函数逻辑、验证两个副作用:
步骤与示例代码
- 先准备测试环境:部署合约
_dim,生成测试用的_investorWallet并给它转ETH - 用
vm.prank(_investorWallet)切换当前调用者为投资者钱包 - 直接调用
_dim.receiveInvestment{value: investmentAmount}(),此时转账和函数逻辑会同时执行 - 最后断言两个副作用:投资者钱包余额减少、合约的
_someStoredValue变为预期值
示例代码:
function test_ReceiveInvestment_UpdatesValueAndBalance() public { uint256 investmentAmount = 1 ether; address _investorWallet = makeAddr("investor"); // 给投资者钱包转ETH vm.deal(_investorWallet, investmentAmount); uint256 initialInvestorBalance = _investorWallet.balance; // 切换调用者为投资者钱包,调用合约函数 vm.prank(_investorWallet); _dim.receiveInvestment{value: investmentAmount}(); // 断言钱包余额减少对应金额 assertEq(_investorWallet.balance, initialInvestorBalance - investmentAmount); // 断言合约变量已更新(假设你有getter函数getSomeStoredValue) assertEq(_dim.getSomeStoredValue(), 15); }
额外注意事项
- 确保
receiveInvestment()函数的权限控制允许_investorWallet调用(比如没有额外的onlyOwner或其他校验) - 如果函数有其他前置条件(比如投资金额下限),要在测试中满足这些条件
- 用
vm.prank()是临时切换下一次调用的身份,vm.startPrank()/vm.stopPrank()可以批量切换多次调用的身份
内容的提问来源于stack exchange,提问作者a.t.
相关产品推荐
相关产品推荐

