Smart Contract Testing with MochaJS

Anindio Daneswara

--

Photo by GC Libraries Creative Tech Lab o, n Unsplash

Well, this is not a post about a mocha coffee as the image above suggested. This time we will explain a bit more about MochaJS, an NPM package in NodeJS used to perform testing. MochaJS is a full feature testing framework, made especially for JavaScript and when we write our smart contract using TruffeJS, means that we can leverage this framework to perform testing against all the functions the smart contract contains.

While this is not a post specifically for Mocha (you can read about it more completely in www.mochajs.org), we will just create a short post about using Mocha for testing. We’ve done many testing on our smart contract functions in previous post (https://daneswa.medium.com/solidity-smart-contract-interaction-and-testing-with-web3-js-and-mocha-3a0467a01805?source=user_profile---------0----------------------------) , so please check that post for more complete walkthrough. We will try to explain the use of Mocha for testing purpose, as simple as it can be, since testing is very important in writing smart contracts because it will involves real money in deploying the smart contracts, even when sending a function/transaction to the MainNet will cost real money.

First of all we need to install Mocha module for testing

npm install mocha --save

Then import all the necessary modules and pass them to variables;

const asset require ('assert');

We will use a very simple JavaScript class, called Car

class Car {

start() {
return 'Car is started';
stop() {
return 'Car is stopped';
}

The class Car will have 2 functions; park() and stop(). Now we will test the function using assert() methods in Mocha so when the class functions are called, they will generate the same values as the values defined in the testing criteria.

MochaJS has 3 components everytime it performs testing ;

  • beforeEach() — will be stated before all the testing methods, usually contains all the repeating arguments/methods so that the commands will executed once only, before executing other commands.
  • describe() — basically a group of testing functions
  • it() — each testing criteria which contains all the functions to perform testing

We will create another instance from class Car

car = new Car();

And since for every testing function we need to declare this instance, we create a global function for car and pass the instance declaration into beforeEach() statement.

let car;beforeEach( () => {
car = new Car;
});

Now we want to create testing functions for each of the class function by passing them to assert methods.

describe('Car', () => {
it('can start', () => {
assert.equal(car.start(), 'Car is started');
it('can stop', () => {
assert.equal(car.stop(), 'Car is stopped');
}

Notice that we use assert.equal() to check the output of the class methods equals to the testing criteria stated in the second argument, in this case ‘Car is started’, and ‘Car is stopped’).

The full testing code will look like this below;

const asset require ('assert');class Car {

start() {
return 'Car is started';
stop() {
return 'Car is stopped';
}
let car;beforeEach( () => {
car = new Car;
});
describe('Car', () => {
it('can start', () => {
assert.equal(car.start(), 'Car is started');
it('can stop', () => {
assert.equal(car.stop(), 'Car is stopped');
}

Testing is sometimes a tedious task after writing hundreds of lines of code, and sometime in a very big team, we have the privilege to pass our code to the QA/Testing to do all the testing tasks. However, in working with smart contracts, where involves real money, sometime we as developer need to think about the logic behind what we want and how we want to test the functions in our smart contract our self.

--

--