Smart contracts are a powerful tool for creating decentralized apps and custom cryptocurrencies. Unlike traditional software, once deployed, they are hard to roll back or patch. And with a market cap of over $200 billion for cryptocurrencies, there’s a lot of value at stake! Unit testing can help us ensure our smart contracts do what we expect.
My initial token had a constructor like this
And migrations/2_deploy_contracts.js looks like this:
Now we can fire up ganache command line interface:
In a separate terminal, let’s deploy this to a test blockchain with
Cool, let’s write our first unit test in Solidity in test/TestMikancoin.sol:
We can use DeployedAddresses to look up where the Mikancoin was deployed, and cast that address to a Mikancoin. Then we can use our asserts to see if our coin is doing the right thing. Running truffle test shows us that we’ve successfully deployed a coin with 100 Mikan and we have a balance of zero.
Here we reach our first problem. It’s not going to be very interesting -- or thorough -- to write tests if we have no tokens to send. Who got the initial mikans? Consider that the migration script made the initial deploy, so it’s probably some internal truffle address that got the fruit. Let’s confirm that by using the tool truffle console:
We can see who called the Mikancoin constructor, and how much gas was spent. We can also see that it matches the first eth address created by ganache-cli. Now we could configure ganache-cli to always generate the same ten addresses, but we still won’t easily be able to control it in solidity. Let’s modify our contract slightly so we can decide who gets the coins on deploy.
We can also write a helper contract to easily manage our Mikancoin.
Next, update the migration script:
And finally, a test where we control the Mikans!
Now, say we want to test the require statements of transfer and ensure we can’t do something bad like send tokens to the zero address. In solidity, this is difficult, as there is no try-catch. We end up with a really awful stack trace when sending to 0x0:
Adding this test and running truffle test generates the following:
TO BE CONTINUED...