1

tdlr; solution

I had to await both of the values used in my assertions. For grabbing the length of the array, I needed to add a new method to my contract, as shown here. The reason for this is in the accepted answer.

function getPeopleSize() public view returns (uint256) {
     return people.length;
}

And here is the passing it block:

it("should add a person and their favorite number", async () => {
  const expectedValue = "11";
  const expectedName = "John";
  const transactionResponse = await simpleStorage.addPerson(
    expectedName,
    expectedValue
  );
  transactionResponse.wait(6);

  const johnValue = await simpleStorage.nameToFavoriteNumber(expectedName);
  const peopleSize = await simpleStorage.getPeopleSize();

  assert.equal(peopleSize, 1);
  assert.equal(johnValue, expectedValue);
});

I have a function addPerson, which stores a new name and favorite number:

function addPerson(string memory _name, uint256 _favoriteNumber) public {
    people.push(People(_favoriteNumber, _name));
    nameToFavoriteNumber[_name] = _favoriteNumber;
}

people is an array and favoriteNumber is a uint256. Both are public data types.

uint256 favoriteNumber;

struct People {
  uint256 favoriteNumber;
  string name;
}

People[] public people;

mapping(string => uint256) public nameToFavoriteNumber;

In my deployed Remix contract, I'm able to call, for example, nameToFavoriteNumber with the string of the user I've added, and the supplied number is returned as expected. However, I'm unsure how to write a test for the addPerson function, to ensure that the name and favorite number are indeed getting stored.

Here's what I've tried. The length of people is printing zero and the mapper prints undefined. I'm expecting it to pass with length equal to 1 and the mapper equal to 11. One final note is that my other tests are passing, so I'm certain that the simpleStorage contract deployed properly in my testing environment.

it("should add a person and their favorite number", async () => {
    const expectedValue = "11";
    const expectedName = "John";
    const transactionResponse = await simpleStorage.addPerson(
      expectedName,
      expectedValue
    );
    transactionResponse.wait(6);

    const people = simpleStorage.people;

    const johnValue = simpleStorage.nameToFavoriteNumber[expectedName];

    assert.equal(people.length, 1);         // prints 0
    assert.equal(johnValue, expectedValue); // prints undefined
});
2

1 Answer 1

1

Somehow I think is missing the keyword await to wait for the contract method promise to be resolved and the () in the end of each method.

Check to see if it helps.

it("should add a person and their favorite number", async () => {
    const expectedValue = "11";
    const expectedName = "John";
    const transactionResponse = await simpleStorage.addPerson(
      expectedName,
      expectedValue
    );

    // added await
    await transactionResponse.wait(6);

    // added await    
    // added () in the end (its a method)    
    // solidity retrieves only the value inside the position you pass. You must create a getPeopleSize method inside the contract to retrieve all length.
    const people = await simpleStorage.people(some index);

    // added await    
    // added () in the end (its a method)    
    const johnValue = await simpleStorage.nameToFavoriteNumber(expectedName);

    assert.equal(people.length, 1);
    assert.equal(johnValue, expectedValue);
});
9
  • 1
    Hey, thanks for the help. Adding the await gets the johnValue assertion to pass. However, the assertion for array length is still failing. It's telling me people is missing an argument? Error: missing argument: passed to contract (count=0, expectedCount=1, code=MISSING_ARGUMENT, version=contracts/5.7.0) Commented Oct 4, 2022 at 19:36
  • Also, the toString() on the mapping assertion was not needed. Commented Oct 4, 2022 at 19:37
  • oh that's correct, cuz you need to pass the index of the array to get it's value (people). So just keep in mind that my answer was to let you able to get values from the contract, now you can go and make the refinements
    – 0xTheL
    Commented Oct 4, 2022 at 19:41
  • I solved my issue creating a method to return the size of the array. I'm not sure why it's needed, but the test is passing. Commented Oct 4, 2022 at 19:41
  • 1
    Sure thing. Please update the answer and I'll update my question with the added getPeopleSize() method that fixed my other test. Commented Oct 4, 2022 at 19:46

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.