6

My contract function returns two values. How to access the multiple return values in JavaScript from a mocha testcase?

contract X {
   function a() pure public returns(uint,uint) {
       uint p=10;
       uint q=20;

       uint add = p+q;
       uint sub = q-p;

       return(add,sub);
   }
}
1
  • Edited to reflect the actual question (see the comment below).
    – ivicaa
    Commented Jan 28, 2019 at 11:27

3 Answers 3

5

I'm not sure the version of web3 used in the previous answer by ivicaa. On web3 "v1.0.0-beta.37", multiple values are actually returned in an Object, not an Array. However, since the returned object has properties named with numbers {0: 'value1', 1:'value2'}, the original answer is completely valid, so one can still access the returned values using the syntax result[0].

If you're using ES6, you could use destructuring assignment with named variables, to have a single-liner.

Example:

Solidity function
// This function will return 03 values
function getData() external view returns (string, bool, uint256) {
    return ("data", true, 15);
}
JS test
const result = await deployedContract.getData({from: accountAddress});
const {0: strValue, 1: boolValue, 2: intValue} = result;

console.log(strValue); // "data"
console.log(boolValue); // true
console.log(intValue); // 15
0
3

I would suggest that you learn how to work with truffle. It helps with compile, test, deploy of smart contracts. It is also based on mocha. For an example of writing unit tests in truffle with JavaScript you can look at https://truffleframework.com/docs/truffle/testing/writing-tests-in-javascript

Moreover, in simple cases, you can write your unit tests in Solidity too. See https://truffleframework.com/docs/truffle/testing/writing-tests-in-solidity

EDIT: Answer to your comment:

In Solidity, you can read multiple returns like this:

(uint add, uint sub) = x.a();

In truffle via web3, it's returned as an array:

x.a().then(function(res){ var add = res[0]; var sub = res[1]; })
3
  • Thank you so much for your listing the resources. But, I know how to write unit test cases using mocha and solidity too. I want to ask if a function has two return parameters then, how to write a test case. How to do assert.equal for that function. I have written a code but it is not working. Can you please tell me how to write the test case for the function a() which is written in the above contract. Commented Jan 28, 2019 at 5:13
  • See the edit of the answer.
    – ivicaa
    Commented Jan 28, 2019 at 6:07
  • Thanks, @ivicaa for your answer. In the morning I have done the changes in the test cases and it's working now. But, I want to do the same using mocha so, I was searching for mocha code or ultimately how can I store two return variable in javascript. In javascript, you can do using an array or JSON string but I don't know how to accept two return variable from solidity inside javascript without web3. Commented Jan 28, 2019 at 11:29
2

In case you are using Truffle, as your function is pure and it requires parameters, use the following:

const {0: variable_1, 1: variable_2} = await contractInstance.yourFunction(param1, param2);

The function call returns a JS dictionary in this case, so make sure to use this data type only.

*For other people using this question as a reference, if your function is not pure/view, the following code works for me:

contractInstance.yourFunction(param1, param2,...).then(function(res){
      var variable_1 = res[0];
      var variable_2 = res[1];
      assert.equal(variable_1, expectedValue1, "value 1 incorrect");
      assert.equal(variable_2, expectedValue2, "value 2 incorrect");
})

There is this post that tells which method would work depending on the function you are working with: https://blockheroes.dev/js-read-multiple-returned-values-solidity/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.