Hardhat中revertedWith匹配自定义错误Raffle__UpkeepNotNeeded失败求助
问题:测试Solidity自定义错误时断言失败
我正在为Lottery合约编写测试,测试触发自定义错误的场景,但遇到了断言失败的问题。
Solidity合约代码
function performUpkeep( bytes calldata /* performData*/ ) external override { (bool upkeepNeeded, ) = checkUpkeep(""); if (!upkeepNeeded) { revert Raffle__UpkeepNotNeeded( address(this).balance, s_players.length, uint256(s_raffleState) ); } s_raffleState = RaffleState.CALCULATING; uint256 requestId = i_vrfCoordinator.requestRandomWords( i_gasLane, // i_subscriptionId, REQUEST_CONFIRMATIONS, i_callbackGasLimit, NUM_WORDS ); emit RequestedRaffleWinner(requestId); }
测试脚本代码
describe("performUpkeep", function () { it("can only run if checkupkeep is true", async () => { await raffle.enterRaffle({ value: raffleEntranceFee }) await network.provider.send("evm_increaseTime", [interval.toNumber() + 1]) await network.provider.request({ method: "evm_mine", params: [] }) const tx = await raffle.performUpkeep("0x") assert(tx) }) it("reverts if checkup is false", async () => { await expect(raffle.performUpkeep("0x")).to.be.revertedWith( `Raffle__UpkeepNotNeeded(0,0,0)` ) }) })
遇到的错误
AssertionError: Expected transaction to be reverted with Raffle__UpkeepNotNeeded(0,0,0), but other exception was thrown: Error: VM Exception while processing transaction: reverted with custom error 'Raffle__UpkeepNotNeeded(0, 0, 0)'
解决方案
原因分析
Waffle的revertedWith匹配的是字符串形式的错误消息,合约抛出的自定义错误参数之间有空格((0, 0, 0)),但测试代码里写的是(0,0,0),格式不匹配导致断言失败。
解决方法1:精确匹配错误字符串
修改测试代码中的错误消息,保留参数间的空格:
it("reverts if checkup is false", async () => { await expect(raffle.performUpkeep("0x")).to.be.revertedWith( `Raffle__UpkeepNotNeeded(0, 0, 0)` ) })
解决方法2:使用自定义错误专用匹配器(推荐)
使用Waffle提供的revertedWithCustomError匹配器,直接匹配错误类型和参数,无需依赖字符串格式:
it("reverts if checkup is false", async () => { await expect(raffle.performUpkeep("0x")) .to.be.revertedWithCustomError(raffle, "Raffle__UpkeepNotNeeded") .withArgs(0, 0, 0); })
这种方式更健壮,后续参数格式变化也不会影响测试结果,只需保证参数值和类型正确即可。
内容的提问来源于stack exchange,提问作者Vasanth Kumar
相关产品推荐
相关产品推荐

