In a previous post, we learned about forking mainnet as an alternative to mock contracts in Solidity. The major drawback with mock contracts is that you need to spend time to rewrite existing smart contracts as mocks. To get exhaustive mock coverage, you’ll end up rewriting whole protocols for the sake of testing.
What if there’s a magical way to mock contract functionality without writing mock contracts? Read on to learn more.
Are you new to smart contracts? Check out the open source Hardhat starter kit! It comes with several useful tools preconfigured such as Typescript, type generation, linting, formatting, and test coverage. Just hit clone and run!
Instant Mocks with Waffle / Smock
You can instantly create mocks with the Waffle (or Smock) testing libraries. Just provide the ABI of the smart contract you want to mock:
You can set the return values for any of your mock’s functions with mock.<nameOfMethod> helpers:
You can also set up reverts using reverts() and revertsWithReason() helpers:
Behind every mock is a real smart contract (with actual Solidity code!) This means you can modify the behavior of individual functions, and leave some functions unmocked. Any values from mocked calls will pass through to be used in the actual contract code.
Let’s try to mock the following contract:
In our unit tests, we will to mock the token.balanceOf() function to return specific values. Mock contracts will be used to supply exactly the values we need to test different scenarios of the MyContract.check() method.
Here’s our unit test using mocks:
Mocks are most effectively used when you need some behavior of a real smart contract but still want the ability to modify things on the fly.
Use the ethereum-waffle (or smock) testing libraries to instantly mock smart contracts, all without writing mock contracts yourself.
A Message From the Author 👋
You reached the end of the article! I hope you found it useful or otherwise interesting. You should follow me on Twitter.
📣Enjoyed this article? Share it.
📬Get updates straight to your inbox.
Subscribe to my newsletter so you don't miss new content.