15

I have a custom error described as such:

error AlreadyListed(address nftAddress, uint256 tokenId);

And in my tests, I'd like to check to see that it's thrown:

expect(await nftMarketplace.listItem(basicNft.address, TOKEN_ID, PRICE)).to.be.revertedWith(`AlreadyListed`)

However, this of course fails with:

 Error: VM Exception while processing transaction: reverted with custom error 'AlreadyListed("0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512", 0)

Do I need to string interpolate with quotes and such, or is there a better way? This looks ugly:

expect(await nftMarketplace.listItem(basicNft.address, TOKEN_ID, PRICE)).to.be.revertedWith(`AlreadyListed("${basicNft.address}", ${TOKEN_ID})`)

4 Answers 4

13

Try moving the await before the expect. e.g.

await expect(nftMarketplace.listItem(basicNft.address, TOKEN_ID, PRICE)).to.be.revertedWith(`AlreadyListed`)

That's what my tests use for custom errors

Hope this helps

2
  • this worked. any idea why it didn't worked when written "await" inside bracket? Commented May 25, 2022 at 11:50
  • 2
    Anything inside the parenthesis will be fully executed before being passed into expect(). Thus, if awaiting the call will fail, expect() will never even be called to check. Instead, we just pass in the Promise<> to expect() and await for expect() to decide what to do -- which it is fully capable of catching and comparing Promise<> errors when used with .to.be.revertedWith() Commented May 26, 2022 at 13:36
22

Update to selected answer

Custom error

hardhat will check for the name of the error, not the contents of the message

MyContract.sol

error SomeCustomError(string message);

contract MyContract {
    function someFunction() public {

        if (!false) {
            revert SomeCustomError("Some error message");
        }
    }
}

MyContract.ts

await expect(contract.call()).to.be.revertedWithCustomError(
  contract,
  "SomeCustomError"
);

got from hardhat docs https://hardhat.org/hardhat-chai-matchers/docs/overview

Basic Revert

MyContract.sol

contract MyContract {

    function someFunction() public payable {
        require(msg.value > 1 ether, "Please send enough ETH");
    }
}

MyContract.ts

await expect(contract.someFunction()).to.be.revertedWith("Some error message");
0

Current hardhat documentation:

await expect(contract.call()).to.be.reverted;

or revert and test the error message:

await expect(contract.call()).to.be.revertedWith("Some revert message");

Example:

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Storage Contract Test", function () {
    let owner;

    beforeEach(async function() {
        [owner] = await ethers.getSigners();

        const SimpleStorage = await ethers
            .getContractFactory("SimpleStorage");

        simpleStorage = await SimpleStorage.deploy();
    });

    
it("should not set a new contract owner to the zero address", async () => {
        //Arrange
        const zeroAddr = "0x0000000000000000000000000000000000000000";
        //Act
        const currentAddr = await simpleStorage.getOwner();
        //Assert
        expect(currentAddr).to.equal(owner.address);
        console.log(currentAddr);
        await expect(simpleStorage.changeOwner(zeroAddr))
            .to.be.reverted;
        await expect(simpleStorage.changeOwner(zeroAddr))
            .to.be.revertedWith("new owner cannot be zero address 0x0")
    });
});
0

Try this,

expect(await nftMarketplace.listItem(basicNft.address, TOKEN_ID, PRICE)).to.be.revertedWithCustomError(nftMarketplace, `AlreadyListed`).withArgs(basicNft.address, TOKEN_ID)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.