Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
flux627 opened this issue Jul 26, 2021 · 2 comments
Open
Labels
waffle-mock-contract Anything related to the mocking package

Comments

@flux627
Copy link

flux627 commented Jul 26, 2021

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.

@rzadp rzadp added the waffle-mock-contract Anything related to the mocking package label Aug 1, 2022
@rzadp
Copy link
Contributor

rzadp commented Nov 10, 2022

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.

@flux627
Copy link
Author

flux627 commented Nov 10, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waffle-mock-contract Anything related to the mocking package
Projects
None yet
Development

No branches or pull requests

2 participants