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
相关产品推荐
相关产品推荐

