如何在Brownie测试中访问合约内初始化合约的公开变量?
问题解决:Brownie测试中通过ContractB访问ContractA变量报错
错误原因
调用toke.A()时,返回的只是ContractA的地址(EthAddress对象),而非绑定了ABI的合约实例,因此无法直接调用合约的emergencyAdmin()方法。
解决方案
方案1:将地址转换为ContractA合约实例
在测试代码中导入ContractA,把返回的地址转换成合约实例后再调用方法:
import pytest from brownie import accounts, ContractB, ContractA def test_tok(): toke = ContractB({'from': accounts[0]}) # 将地址转换为ContractA合约实例 contract_a_instance = ContractA.at(toke.A()) # 调用public变量的getter方法 print(contract_a_instance.emergencyAdmin())
方案2:在ContractB中封装访问方法
如果不想修改测试代码,可以在ContractB中新增一个函数,直接返回ContractA的emergencyAdmin值:
修改ContractB代码:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../token/ContractA.sol"; contract ContractB{ ContractA public A = new ContractA("Test Token", "TEST", address(this)); uint256 public totalStakes; constructor() {} // 新增方法,直接返回ContractA的emergencyAdmin function getContractAEmergencyAdmin() external view returns(address) { return A.emergencyAdmin(); } receive() external payable { } }
对应的测试代码修改为:
import pytest from brownie import accounts, ContractB def test_tok(): toke = ContractB({'from': accounts[0]}) print(toke.getContractAEmergencyAdmin())
方案选择
- 方案1适合无法修改合约的场景,直接在测试层处理合约实例转换
- 方案2适合希望通过合约层封装访问逻辑,让测试代码更简洁的场景
内容的提问来源于stack exchange,提问作者FaizanNehal
相关产品推荐
相关产品推荐

