PatrickAlphaC / hardhat-fund-me-fcc

82 stars 183 forks source link

Custom Error in Revert wasn't detected by test code. #89

Open eric573 opened 1 year ago

eric573 commented 1 year ago

I encountered a weird issue while writing the Only allows the owner to withdraw test. More specifically, I get the an assertion error stating that the expected assertions wasn't seen.

Test Failure Message

     AssertionError: Expected transaction to be reverted with reason 'FundMe__NotOwner', but it reverted with a custom error

Unit Test Code

        it("Only allows the owner to withdraw", async function () {
            const accounts = await ethers.getSigners()
            const attacker = accounts[1]
            const attackerConnectedContract = await fundMe.connect(attacker)
            await expect(
                attackerConnectedContract.withdraw()
            ).to.be.revertedWith("FundMe__NotOwner")
            // console.log(await attackerConnectedContract.withdraw())
        })

FundMe.sol modifier details

    error FundMe__NotOwner();
    // 7. Modifier
    modifier onlyOwner {
        // require(msg.sender == owner);
        if (msg.sender != i_owner) revert FundMe__NotOwner();
        _;
    }

    // Showing that withdraw uses the onlyOwner modifier
    function withdraw() public onlyOwner {...}

What I did to debug Added a console.log statement to ensure that the error thrown is indeed FundMe__NotOwner, and I have the following observation. The code console.log(await attackerConnectedContract.withdraw()) generates this ouput

     Error: VM Exception while processing transaction: reverted with custom error 'FundMe__NotOwner()'

Based on this observation, I know that the FundMe__NotOwner() error is being thrown, however, the testing framwork wasn't able to pick up on this error type. How should I go about this?

SimSimButDifferent commented 1 year ago

I also have the very same issue... Still haven't managed to debug yet, let you know if I do.

DaviPiove commented 1 year ago

Hi! By removing the await before the expect statement solved the issue for me:

expect(attackerConnectedContract.withdraw()).to.be.revertedWith(
    "FundMe__NotOwner"
);

You can also use the method revertedWithCustomError(contract, "custom_error_name")

await expect(
    attackerConnectedContract.withdraw()
).to.be.revertedWithCustomError(fundMe, "FundMe__NotOwner");
e2hope commented 1 year ago

Oh thanks. I had the same issue and solved by this suggestion .