Waffle icon indicating copy to clipboard operation
Waffle copied to clipboard

Allow function to be passed to `MockContract#mock.<contractFunction>.returns`

Open flux627 opened this issue 4 years ago • 2 comments

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

  1. be more semantically clear that these are side-effects of calling the contract method
  2. 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.

flux627 avatar Jul 26 '21 16:07 flux627

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.

rzadp avatar Nov 10 '22 14:11 rzadp

I don't remember the exact context I needed this when posting, however I still think this feature would be useful.

flux627 avatar Nov 10 '22 15:11 flux627