You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Consensys供应链练习:Truffle测试异常类型不符问题咨询

问题分析与解决方案

问题描述

克隆ConsenSys的supply-chain-exercise仓库后,运行truffle test时,23个@openzeppelin/test-helpers测试用例仅通过22个,剩余1个失败。报错显示:实际返回带原因的revert异常(VM Exception while processing transaction: revert Not enough payment sent -- Reason given: Not enough payment sent.),但测试预期的是invalid opcode异常。

相关代码

SupplyChain.sol 关键片段

modifier paidEnough(uint _price) { 
  require(msg.value >= _price, "Not enough payment sent");
  _;
}

function buyItem(uint sku) public payable forSale(sku) paidEnough(items[sku].price) checkValue(sku) {
  items[sku].seller.transfer(items[sku].price);
  items[sku].buyer = msg.sender;
  items[sku].state = State.Sold;
  emit LogSold(sku);
}

supply_chain.test.js 关键测试用例

it("should error when not enough value is sent when purchasing an item", async () => {
  await instance.addItem(name, price, { from: alice });
  await expectRevert.assertion(instance.buyItem(0, { from: bob, value: 1 }));
});

问题根源

这个测试失败完全和上述代码相关,核心矛盾是测试断言的异常类型与合约实际抛出的异常类型不匹配:

  • 合约中paidEnough修饰器使用了带自定义错误信息的require语句,触发时会抛出带原因的revert异常
  • 测试中使用的expectRevert.assertion()方法,专门用于断言invalid opcode类型的异常(比如早期Solidity不带原因的revert、assert失败或未处理的throw),无法匹配带原因的revert,因此测试报错

修复方案

将测试中的expectRevert.assertion()替换为expectRevert(),并可选择传入对应的错误信息以精确匹配:

it("should error when not enough value is sent when purchasing an item", async () => {
  await instance.addItem(name, price, { from: alice });
  // 精确匹配错误信息
  await expectRevert(instance.buyItem(0, { from: bob, value: 1 }), "Not enough payment sent");
});

如果不需要精确匹配错误信息,也可以简化为:

await expectRevert(instance.buyItem(0, { from: bob, value: 1 }));

内容的提问来源于stack exchange,提问作者tannertanner1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:50:30