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 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 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 at 17:30
  • Your test passed or it returns error?
    – Alireza
    Mar 5 at 17:53
  • It returned error Mar 6 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 that you have read and understand our privacy policy and code of conduct.

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