2

I'm writing Unit Test using hardhat for a solidity contract. There is a public mapping variable which has a mapping of address to array of struct.

 struct ticket {
        uint16 looteryID;
        uint ticketPrice;
        uint ticketSerialNo;
    }

mapping(address => ticket[]) public activeTickets;

function buyLottery(uint16 _id) payable public {
    activeTickets[msg.sender].push(ticket(_id,10,100));
}

I want to write unit test where I want to check the length of ticket array in activeTickets for msg.sender (anyone who is calling buyLottery function). I tried few hit and trail but all failed. Below is one of the attempts which failed.

Unit Test Code

 it("User can buy lottery",async () => { 
await lotteryInstance.connect(addr1).buyLottery(1,{value: ethers.utils.parseEther('1')});
        const userTickets = await lotteryInstance.activeTickets(addr1.address);
             expect(userTickets.length).equal(1);
             expect(userTickets[0].looteryID).equal(1);
            });

This will push and ticket details to activeTickets. If we assume msg.sender is 0xFe123d4 then activeTickets should have something like 0xFe123d4 => [{1,10,100}] Now I want to test whether activeTickets was successfully updated or not, by checking current length of ticket w.r.t address 0xFe123d4 and also by accessing and comparing the pushed value.

7
  • What you mean exactly? if you explain more what is your problem probably i can help you
    – Alireza
    Mar 5, 2023 at 11:07
  • But it seems that your test code doesn't check anything, it just call function of your contract then log the userTickets
    – Alireza
    Mar 5, 2023 at 11:09
  • @Alireza, thanks for responding. I have updated the question with some more clarification on what exactly I want to achieve. Mar 5, 2023 at 17:30
  • Your test passed or it returns error?
    – Alireza
    Mar 5, 2023 at 17:53
  • It returned error Mar 6, 2023 at 2:31

1 Answer 1

0

Try this way:

 struct ticket {
        uint16 looteryID;
        uint ticketPrice;
        uint ticketSerialNo;
    }

mapping(address => ticket[]) public activeTickets;

function buyLottery(uint16 _id) payable public {
    activeTickets[msg.sender].push(ticket(_id,10,100));
}

function getLooteryID(uint256 index, address userAddress) external view returns(uint16) { 
   return activeTickets[userAddress][index].looteryID;
}

function getLength(address userAddress) external view returns(uint256) {
    return return activeTickets[userAddress].length;
}

and in the test file:

 it("User can buy lottery",async () => { 
const lotteryConnectedToSigner = await lotteryInstance.connect(addr1)
await lotteryConnectedToSigner.buyLottery(1,{value: ethers.utils.parseEther('1')});
const userTickets = await lotteryConnectedToSigner.getLooteryID(0,addr1.address);
const length = lotteryConnectedToSigner.getLength(addr1.address)
             expect(length).equal(1);
             expect(userTickets[0].looteryID).equal(1);
            });

Also you can get all of mapping data using one function and get details after calling function, here to simplify i prefer using 2 separate functions to get looteryID and length.

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.