Allow function to be passed to `MockContract#mock.<contractFunction>.returns`
If we were to allow an (optionally async) function to be passed to MockContract#mock.<contractFunction>.returns and MockContract#mock.<contractFunction>.withArgs(...).returns, then we could mock any side-effects that calling that contract function would normally cause. My proposed signature would be:
(contract: MockContract) => Promise<any> | any
where contract is the mocked contract, and the returned (promise-resolved) value is passed as the contract function's mocked value.
My use-case: I'm testing a contract that interacts with a Compound ERC20 (CERC20). When my contract calls redeemUnderlying on this CERC20, I have to separately update the mocked value of balanceOf and also call the underlying mocked ERC20 to send tokens to my contract. It would be nice to be able to define these actions this way, as it would
- be more semantically clear that these are side-effects of calling the contract method
- execute the actions in the correct order, since the actions would run before returning the mocked value
To show an example of what this would look like (using Hardhat + Typescript):
export async function deployMockContract(deployer: Signer, anotherMock: MockContract): Promise<MockContract> {
const artifact: Artifact = await hre.artifacts.readArtifact('ContractToMock')
const mockContract: MockContract = await hre.waffle.deployMockContract(deployer, artifact)
await mockContract.mock.doThingWithSideEffects.returns(async (contract: MockContract) => {
// update getter for state var
await contract.mock.someStateVar.returns('new affected value')
// update another affected mock contract
await anotherMock.mock.someValue.returns('affected by other contract')
return 'this is a mocked return value'
})
return mockContract
}
I am able and willing to contribute to writing this feature if maintainers would be open to its inclusion.
Hey @flux627 Sorry it took some time to get back to you.
Is this still a feature request you're looking for? Or did you find a different means to achieve your goal?
We're open to collaborate on this one.
I don't remember the exact context I needed this when posting, however I still think this feature would be useful.