I'm writing an ERC-721 contract but I'm struggling to write a proper unit test when all token ids are minted.
Function I want to test:
uint256 public constant MAX_SUPPLY = 10000;
function safeMint() public payable {
uint256 totalSupply = totalSupply();
require(totalSupply <= MAX_SUPPLY, "Purchase would exceed max supply");
//...
}
In the code above I want to write a unit test so it would throw an error if total supply has reached its limit.
My first approach was to mock totalSupply() so it would return 10,000. Then I would call safeMint() and assert it throws an error with the correct error message.
So my question is how to mock the return value of a function? Or is there some other way to test this?
I tried something like this with hardhat, waffle and smock:
describe('MyContract', () => {
describe('given mocked contract', () => {
let mockInstance;
let account;
beforeEach(async () => {
const myContractFactory = await smock.mock('MyContract');
mockInstance = await myContractFactory.deploy();
[account] = await ethers.getSigners();
});
it('given 10,000 tokens ids minted, when safe mint is called, throws', async () => {
await mockInstance.totalSupply.returns(10000);
await expect(
mockInstance.connect(account).safeMint({
value: ethers.utils.parseEther('0.123'),
})
).to.be.revertedWith('Purchase would exceed max supply');
});
});
});
Above code sets the total supply to 10,000 but when safeMint() is called it does not throw an error.