Testing our token sale contract

The tests for out token sale contract will be slightly more involved as they will require references to both our contracts.

We will start by creating a new file, PacktTokenSale.test.js, in the test/ directory of our project. At the head of the file we require abstractions of both contracts:

var PacktTokenSale = artifacts.require('./PacktTokenSale.sol');
var PacktToken = artifacts.require('./PacktToken');

We can then set up some variables for use during the tests:

contract('PacktTokenSale', async (accounts) => {
let owner = accounts[0];
let buyer = accounts[1];
let tokensToSell = 500000;
let tokenPrice = 1000000000000000;
let numberOfTokens;
...
});

We are using Ganache's first address as the owner of the sale, and its second address as the participant in the sale. The tokensToSell value equates to 50% of the token supply defined in our token contract deployment. In a real token sale, the owner of the contracts would be responsible for allocating the desired amount of token to the token sale contract. In our token sale test, we are allocating 50%.

Again, we won't write an exhaustive set of tests here, but will cover enough to give an idea of how to write further tests. We'll aim to cover enough to check that both buying tokens and transferring them between addresses works correctly. Our first test will check that both contracts have been deployed, and that the token price has been set correctly by the constructor of the token sale contract:

 it ('initialises the contract with the correct values', async () => {
let tokenSaleInstance = await PacktTokenSale.deployed();

let tokenSaleAddress = await tokenSaleInstance.address;
assert.notEqual(tokenSaleAddress, 0x0, 'has an address');

let tokenAddress = await tokenSaleInstance.tokenContract();
assert.notEqual(tokenAddress, 0x0, 'has an address');

let tokenPrice = await tokenSaleInstance.tokenPrice();
assert.equal(tokenPrice,
1000000000000000,
'sets the correct token price');
});

Our next test is more involved and checks the buying functionality:

 it ('allows users to buy tokens', async () => {
let tokenSaleInstance = await PacktTokenSale.deployed();
let tokenInstance = await PacktToken.deployed();

// Transfer half of the tokens to the sale contract.
let success = await tokenInstance.transfer(
tokenSaleInstance.address, tokensToSell, { from: owner });

numberOfTokens = 40;
let receipt = await tokenSaleInstance.buyTokens(
numberOfTokens,
{ from: buyer, value: numberOfTokens * tokenPrice });

let buyerBalance = await tokenInstance.balanceOf(buyer);
assert.equal(buyerBalance, numberOfTokens);

let contractBalance = await tokenInstance.balanceOf(
tokenSaleInstance.address);
assert.equal(contractBalance, tokensToSell - numberOfTokens);
});

Here's a breakdown of what's happening:

  • We first get a reference to both deployed contracts.
  • As in a real token sale, before the sale starts, we allocate a proportion of the tokens to the sale contract, here 50%.
  • The buyer account buys a set number of tokens from the token sale contract.
  • We then check that the balances of the buyer and token sale contract have been updated correctly in the token contract.

In this test, we have checked that both the token sale contract's buying functionality and the token contract's transfer functionality work.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset