Published on

Easily Testing Solidity Structs in JavaScript

Authors

In a previous post I spoke about how structs from Solidity get returned as an array on the JavaScript side. With JavaScript you can destructure the array to make your code more readable as below for example:

const [name, surname, age] = yourContract.getPerson(hashForJohn)

On the Solidity side the struct looks as follows:

struct Person {
   string name;
   string surname;
   uint age;
}

Today while testing I came up with a better approach. The problem with using a destructured array is when you assert each element of this returned object you need multiple expect/assert statements which makes this code less readable:

expect(name).to.equal('John')
expect(surname).to.equal('Smith')
expect(age.toNumber()).to.equal(33)

With every new field we add we need a new assert/expect statement to test it.

A cleaner approach is to use a helper function which transforms the array returned to JSON which is much easier to test and you can add any common transformations like turning BigNumbers(BNs) to standard ints. The transformer function would look as follows in JavaScript:

function personFieldArrayToJSON(personFieldArray) {
  const [name, surname, age] = personFieldArray

  return {
    name,
    surname,
    age: age.toNumber(),
  }
}

We then update our test as follows:

const personFieldArray = yourContract.getPerson(hashForJohn)

expect(personFieldArray).to.eql({
  name: 'John',
  surname: 'Smith',
  age: 33,
})

Note how we use eql instead of equal. eql is how you do a deep comparison with Mocha.

Using the above approach we can easily add/remove new fields and if it fails Mocha clearly indicates which fields in your result object break if something does break.