1

I have 5 smart contract functions and 26 unit tests for them. If I run the tests together, they run green, however, in the end, I get a timeout error: timeout

The error message wasn't quite informative for me, so I started to comment out the tests one by one, and all of my tests seem to be good together until I add a particular one (see below).

The relevant smart contract function:

mapping(uint256=>bytes32[]) idRowArrayMapping;

event QueryResultStored(
    uint256 queryId,
    uint256 resultId
);
event RowStored();
event Error(string errorMessage);

enum ViewResultCodes { Success, NoMatchFound, IntegerNotPositive, StringEmpty }
ViewResultCodes public viewResultCode;

function validateRow(uint256 _resultId, string _rowString) external view returns (ViewResultCodes result) {
    if (_resultId <= 0) {
      return ViewResultCodes.IntegerNotPositive;
    }
    if (bytes(_rowString).length == 0) {
      return ViewResultCodes.StringEmpty;
    }

    bytes32 rowHash = keccak256(_rowString);
    bytes32[] storage dataSet = idRowArrayMapping[_resultId];

    for (uint i = 0; i < dataSet.length; i++) {
      if (dataSet[i] == rowHash) {
        return ViewResultCodes.Success;
      }
    }
    return ViewResultCodes.NoMatchFound;
  }

And the unit test for it:

'use strict';

const QueryResultHandler = artifacts.require("./QueryResultHandler");
const ViewResultCodes = {
  Success: 0,
  NoMatchFound: 1,
  IntegerNotPositive: 2,
  StringEmpty: 3
};

let instance;

contract('validateRow() function test', function() {
  beforeEach('Setup contract for each test', async function() {
    instance = await QueryResultHandler.deployed();
  });

  it("(0,'a'): Should return the StringEmpty code", async () => {
    instance.validateRow.call(0,'a').then(function(viewResultCode) {
      assert.equal(viewResultCode, ViewResultCodes.IntegerNotPositive, "Returned code was: " + viewResultCode);
    });
  })
})

Also, if I run the test alone, there is no timeout and it works fine. I would be grateful for any ideas, what can be the problem.

2
  • 1
    Mixing promises and async/await can create some problems (I think perhaps your test is finishing before the calls complete). Try const viewResultCode = await instance.validateRow.call(0,'a'); assert.equal(viewResultCode, ViewResultCodes.IntegerNotPositive, "Returned code was: " + viewResultCode);
    – Ismael
    Commented Apr 15, 2018 at 14:19
  • Wow, thanks a lot, it worked! Can you please post this as an answer?
    – Antona
    Commented Apr 15, 2018 at 14:53

1 Answer 1

2

Mixing promises and async/await can create some problems if you are not very careful.

I think your test finishes while the call is still running. To ensure the call completes before the test ends try waiting for the result:

it("(0,'a'): Should return the StringEmpty code", async () => {
  const viewResultCode = await instance.validateRow.call(0,'a');
  assert.equal(viewResultCode, ViewResultCodes.IntegerNotPositive, "Returned code was: " + viewResultCode);
});

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.