Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Lesson 6: Hardhat Testing/Coverage Homework #483

pyromaus started this conversation in Ideas
Discussion options

Here I share how I wrote the coverage test for the 3rd Simple Storage function (.addPerson)

it("Should update 'people' struct with name and fav number", async function () {
 const expectedFavNumber = "77777"
 const expectedName = "serge"
 const simpleTx = await simpleStorage.addPerson(
 expectedName,
 expectedFavNumber
 )
 await simpleTx.wait(1)
 const currentName = (await simpleStorage.people(0)).name
 assert.equal(currentName, expectedName)
 const currentFavNumber = await simpleStorage.nameToFavoriteNumber(
 currentName
 )
 assert.equal(currentFavNumber.toNumber(), expectedFavNumber)
 })

Tests all went through, and coverage shows 100%

@RevanthGundala's way of coding this was more concise and clean.
What I found interesting that may be helpful for other noobs like myself is the difference parentheses () around await simpleStorage.people(0) made. From Revanth's thread, @TilakMaddy suggested parentheses that saves you lines of code.. Hardhat console:

> withoutParentheses = await simpleStorage.people(0).name
undefined
> withoutParentheses.toString()
Uncaught TypeError: Cannot read properties of undefined (reading 'toString')
> withParentheses = (await simpleStorage.people(0)).name
'serge'
> withParentheses.toString()
'serge'
> withParentheses == withParentheses.toString()
true

If I'm not mistaken I imagine it like this;
Without parenthesis, the await is awaiting this entire statement: simpleStorage.people(0).name including the name, which will not compute.
With parenthesis, you're waiting for this phrase await simpleStorage.people(0) to go through before fetching name. It's like those unnamed/"anonymous" functions Patrick mentioned. The parentheses let you make an anonymous variable that's used right then and there and never stored.

// So instead of
const person = await simpleStorage.people(0)
const currentName = person.name
// You can simply do
const currentName = (await simpleStorage.people(0)).name

Thanks for listening to my rant, lemme know if this ain't it

You must be logged in to vote

Replies: 3 comments 1 reply

Comment options

@pyromaus Yes, when you do await (simpleStorage.people(0).name) it will try to access the name parameter that is still not available because the people(0) is not received yet. Doing (await simpleStorage.people(0)).name will first get the people(0) and then try to get the name and this way we will not get the error.

You must be logged in to vote
1 reply
Comment options

You got it :)

Comment options

so that's how you do it! I didn't know how to get it to work so I cheated and modified the smart contract

 function retrievePeople() public view returns (People[] memory) {
 return people;
 }
 function retrieveMapping(string memory _name) public view returns (uint256) {
 return nameToFavoriteNumber[_name];
 }

and then finally got 100% wit this monster of a code

it("Should add new person to the people array and add their favorite number to mapping", async function () {
 const peopleBefore = await simpleStorage.retrievePeople()
 const expectedPerson = "roberto"
 const expectedFavoriteNumber = 23
 const transactionResponse = await simpleStorage.addPerson(
 expectedPerson,
 expectedFavoriteNumber
 )
 await transactionResponse.wait(1)
 const peopleAfter = await simpleStorage.retrievePeople()
 const personAfter = peopleAfter[peopleAfter.length - 1].name
 const favoriteNumberAfter =
 peopleAfter[peopleAfter.length - 1].favoriteNumber
 const numberFromMapping = await simpleStorage.retrieveMapping(
 expectedPerson
 )
 assert.isAbove(peopleAfter.length, peopleBefore.length)
 assert.equal(personAfter, expectedPerson)
 assert.equal(favoriteNumberAfter, expectedFavoriteNumber)
 assert.equal(numberFromMapping, expectedFavoriteNumber)
 })
You must be logged in to vote
0 replies
Comment options

Thanks for sharing your experience @pyromaus! I was unable to get it right without the parenthesis.
After reading your explanation, it makes a lot of sense actually.

This is my final result using typescript. I also wanted to know what would happen if you cover two asserts in 1 it, so I compared the output of the function nameToFavoriteNumber to the expectedValue variable.

Conclusion: if all the asserts passes the test, you'll get your green checks, if one single assert fails, the test fails.

 it("Should add a new person with a favorite number to the people array", async () => {
 const transactionResponse: ContractTransactionResponse = await simpleStorage.addPerson("satoshi", "21000000")
 await transactionResponse.wait(1)
 const expectedValue: string = "21000000"
 const nameToFavoriteNumberValue: string = (await simpleStorage.nameToFavoriteNumber("satoshi")).toString()
 const firstPersonPeopleArrFavoriteNumber: string = ((await simpleStorage.people(0)).favoriteNumber).toString()
 // const testValue = 8
 
 assert.equal(nameToFavoriteNumberValue, expectedValue)
 assert.equal(firstPersonPeopleArrFavoriteNumber, expectedValue)
 // assert.equal(testValue.toString(), "1")
 })
You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /