// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
contract Error {
error NotAuthorized();
function throwError() external {
require(false, "not authorized");
}
function throwCustomError() external {
revert NotAuthorized();
}
}
Test file:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;
import "forge-std/Test.sol";
import {Error} from "../src/Error.sol";
contract ErrorTest is Test {
Error public err;
function setUp() public {
err = new Error();
}
function testFail() public {
err.throwError();
}
function testRevert() public {
vm.expectRevert();
err.throwError();
}
function testRequireMessage() public {
vm.expectRevert(bytes("not authorized"));
err.throwError();
}
function testCustomError() public {
vm.expectRevert(Error.NotAuthorized.selector);
err.throwCustomError();
}
// Add label to assertions
function testErrorLabel() public {
assertEq(uint256(1), uint256(1), "test 1");
assertEq(uint256(1), uint256(1), "test 2");
assertEq(uint256(1), uint256(1), "test 3");
assertEq(uint256(1), uint256(2), "test 4");
assertEq(uint256(1), uint256(1), "test 5");
}
}
vm.expectRevert()
If we want a test case to simply revert, use testFail prefix in the function name:
function testFail() public {
err.throwError();
}
Another way of doing the same thing is to use test prefix in the function name and vm.expectRevert() before that operation:
function testRevert() public {
vm.expectRevert();
err.throwError();
}
Test require error message
If we want to test for a require() statement's error message, such as the following:
function throwError() external {
require(false, "not authorized");
}
use vm.expectRevert(bytes(error_message)):
function testRequireMessage() public {
vm.expectRevert(bytes("not authorized"));
err.throwError();
}
Custom error
If we want to test for custom error instead, such as the following:
function throwCustomError() external {
revert NotAuthorized();
}
use vm.expectRevert(Error.custom_error_name.selector):
function testCustomError() public {
vm.expectRevert(Error.NotAuthorized.selector);
err.throwCustomError();
}
Label assertions
If we have a lot of assertions in a test case, Foundry won't tell us which ones succeed and which ones fail. For example:
function testErrorLabel() public {
assertEq(uint256(1), uint256(1));
assertEq(uint256(1), uint256(1));
assertEq(uint256(1), uint256(1));
assertEq(uint256(1), uint256(2));
assertEq(uint256(1), uint256(1));
}
The 4th assertion clearly would fail but Foundry won't tell us the failed one is the 4th assertion. In order to distinguish assertions, we can label them with different names:
// Add label to assertions
function testErrorLabel() public {
assertEq(uint256(1), uint256(1), "test 1");
assertEq(uint256(1), uint256(1), "test 2");
assertEq(uint256(1), uint256(1), "test 3");
assertEq(uint256(1), uint256(2), "test 4");
assertEq(uint256(1), uint256(1), "test 5");
}