将Mocha测试转为livedoc-mocha及mocha-cakes-2适配问题
问题1:livedoc-mocha 作用域与Background执行次数问题
问题分析
- 直接将Feature包裹在contract块内会导致变量作用域隔离,
staker这类在contract中定义的变量无法被Feature内的Scenario访问,引发未定义错误。 - livedoc-mocha的Background默认会在每个Scenario执行前运行一次,不符合全局仅初始化一次的需求。
解决方案
1. 调整变量作用域与初始化方式
不要把整个Feature嵌套进contract块,而是在contract外部定义全局变量,或用mocha原生的before()钩子在contract内完成全局初始化,Feature直接引用这些变量:
let staker; let rocketDepositPool; contract('RocketDepositPool', accounts => { // 全局初始化,整个测试套件仅执行一次 before(async () => { staker = accounts[0]; rocketDepositPool = await RocketDepositPool.deployed(); // 其他全局初始化操作,比如设置初始状态 }); Feature('RocketDepositPool 存款测试') .Scenario('用户存入ETH', async () => { // 直接使用已初始化的变量,无作用域问题 await rocketDepositPool.deposit({ from: staker, value: ethers.utils.parseEther('1') }); }); });
2. 替换Background为mocha原生钩子
放弃livedoc-mocha的Background,改用mocha的before()(全局一次)或beforeEach()(每个Scenario一次)来控制初始化时机,完全符合全局初始化需求。
问题2:mocha-cakes-2 中rETH汇率未更新导致断言失败
问题分析
更新网络ETH总量后rETH汇率未变化,大概率是因为:
- 合约未自动触发汇率计算,需要主动调用更新方法;
- 汇率依赖区块高度/时间,未模拟区块生成触发更新;
- ETH总量更新操作未正确执行(参数错误、合约实例错误)。
解决方案
1. 主动触发汇率更新
多数rETH类合约不会实时自动更新汇率,需要手动调用合约内的汇率刷新方法(比如updateExchangeRate()):
// 先记录更新前的汇率 const rateBefore = await rocketTokenRETH.getExchangeRate(); // 执行ETH总量更新操作 await rocketDepositPool.updateTotalETH(ethers.utils.parseEther('100000')); // 主动调用汇率更新方法 await rocketTokenRETH.updateExchangeRate(); // 获取更新后的汇率 const rateAfter = await rocketTokenRETH.getExchangeRate(); assertBN.notEqual(rateBefore, rateAfter);
2. 模拟区块生成
如果合约汇率计算依赖区块高度,更新ETH总量后需要模拟挖矿生成新区块(以Hardhat为例):
const rateBefore = await rocketTokenRETH.getExchangeRate(); await rocketDepositPool.updateTotalETH(ethers.utils.parseEther('100000')); // 模拟挖矿,生成新区块 await hre.network.provider.send('evm_mine'); const rateAfter = await rocketTokenRETH.getExchangeRate(); assertBN.notEqual(rateBefore, rateAfter);
3. 验证ETH总量更新操作正确性
检查调用updateTotalETH时的参数是否正确(比如是否用parseEther转换为合约支持的大数类型),以及是否使用了正确的合约实例,确保ETH总量确实被更新。
内容的提问来源于stack exchange,提问作者user2007843
相关产品推荐
相关产品推荐

