expectRevert
Signature
function expectRevert() external;
function expectRevert(bytes4 msg) external;
function expectRevert(bytes calldata msg) external;
Description
If the next call does not revert with the expected message msg
, then expectRevert
will.
After calling expectRevert
, calls to other cheatcodes before the reverting call are ignored.
This means, for example, we can call prank
immediately before the reverting call.
There are 3 signatures:
- Without parameters: Asserts that the next call reverts without a message.
- With
bytes4
: Asserts that the next call reverts with the specified 4 bytes. - With
bytes
: Asserts that the next call reverts with the specified bytes.
⚠️ Gotcha: Usage with low-level calls
Normally, a call that succeeds returns a status of
true
(along with any return data) and a call that reverts returnsfalse
.The Solidity compiler will insert checks that ensures that the call succeeded, and revert if it did not.
The
expectRevert
cheatcode works by inverting this, so the next call after this cheatcode returnstrue
if it reverts, andfalse
otherwise.The implication here is that to use this cheatcode with low-level calls, you must manually assert on the call's status since Solidity is not doing it for you.
For example:
function testLowLevelCallRevert() public { vm.expectRevert(bytes("error message")); (bool status, ) = address(myContract).call(myCalldata); assertTrue(status, "expectRevert: call did not revert"); }
Examples
To use expectRevert
with a string
, convert it to bytes
.
vm.expectRevert(bytes("error message"));
To use expectRevert
with a custom error type without parameters, use its selector.
vm.expectRevert(MyContract.CustomError.selector);
To use expectRevert
with a custom error type with parameters, ABI encode the error type.
vm.expectRevert(
abi.encodeWithSelector(MyContract.CustomError.selector, 1, 2)
);
If you need to assert that a function reverts without a message, you can do so with expectRevert()
.
function testExpectRevertNoReason() public {
Reverter reverter = new Reverter();
vm.expectRevert();
reverter.revertWithoutReason();
}
You can also have multiple expectRevert()
checks in a single test.
function testMultipleExpectReverts() public {
vm.expectRevert(abi.encodePacked("INVALID_AMOUNT"));
vault.send(user, 0);
vm.expectRevert(abi.encodePacked("INVALID_ADDRESS"));
vault.send(address(0), 200);
}
SEE ALSO
Forge Standard Library