1

I'm a beginner with Solidity, and I'm working on a smart contract that mints an NFT and stores relevant information inside a struct. The issue I'm currently facing is that when testing the fetchMarketItems() function, which is supposed to return an array of structs, I encounter the following error with the current implementation.

TypeError: Type struct NFTMarketplace.MarketItem[] memory is not implicitly convertible to expected type struct ContractTest.MarketItem[] memory.

The function to test

function testfetchMarketItems() public returns(MarketItem[] memory) {
        testCreateToken(); // test function to create tokens and it's passed
        MarketItem[] memory items = propertyRecorder.fetchMarketItems();
        // console2.log("Return Items", items[1]);  
    }

Can you propose any solution on how to implement the same return type with the testfetchMarketItems() function in Foundry as it is in the smart contract? Also, how to compare that the function output is the same as it was expected? This the contracts that I'm trying to test https://github.com/dabit3/polygon-ethereum-nextjs-marketplace/blob/main/contracts/NFTMarketplace.sol Thanks!

1 Answer 1

2

I can read from the error that you are comparing two instances of MarketItem that seem to be defined in two different contracts (ContractTest vs NFTMarketPlace).

I guess you have copied the MarketItem struct into your ContractTest and in your tests you are comparing NFTMarketPlace.MarketItem against ContractTest.MarketItem. The two structs look the same but belong to different contracts. Therefore, even though they are called the same, the EVM understands them as different objects that cannot be compared.

To fix it, when yo instanciate the MarketItem you have do it using specifically the one from your NFTMarketPlace like this:

NFTMarketPlace.MarketItem marketItemFromContract = nftMarketPlaceInstance.getMarketItem(...);

NFTMarketPlace.MarketItem marketItemFromTest = NFTMarketPlace.MarketItem(values,here,to,instanciate,item)

In that way, marketItemFromContract and marketItemFromTest will be of the same type.

----------------- EDIT ------------------------

However, after testing it, it turns out you cant really compare structs even if they are defined with the same type. So the approach here would be to compare the fields one by one. Please see the following example:

pragma solidity ^0.8.16;

import "lib/forge-std/src/Test.sol";

contract LockerContract {
    struct Lock {
        uint256 amount;
        uint256 releaseTime;
    }

    Lock timelock;

    function createTimelock() public {
        timelock = Lock(100, 1000);
    }

    function getTimelock() public view returns (Lock memory) {
        return timelock;
    }
}

contract TestStruct is Test {
    LockerContract locker;

    function setUp() public {
        locker = new LockerContract();
    }

    function testCompareStructs() public {
        locker.createTimelock();

        LockerContract.Lock memory lock = locker.getTimelock();
        LockerContract.Lock memory localLoc = LockerContract.Lock(100, 1000);

        // these two comparisons will fail:
        //        assert(lock == localLoc);
        //        assertEq(lock, localLoc);

        assertEq(lock.amount, localLoc.amount);
        assertEq(lock.releaseTime, localLoc.releaseTime);
    }
}

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.