LimeChain / matchstick

🔥 Unit testing framework for Subgraph development on The Graph protocol. ⚙️
MIT License
207 stars 17 forks source link

How to mock `getPool(address,uint256):((address,string))` #384

Closed matstyler closed 1 year ago

matstyler commented 1 year ago

Hi. I am using matchstick for some time already but today I have got a bit different test scenario and I do not know how to cover returns for this kind of function:

getPool(address,uint256):((address,string))

I tried

.returns([
ethereum.Value.fromArray([
                    ethereum.Value.fromAddress(FIRST_POOL_ADDRESS_MOCK),
                    ethereum.Value.fromString("String"),
                ]),
            ])

and

.returns([ethereum.Value.fromTuple([
                    ethereum.Value.fromAddress(FIRST_POOL_ADDRESS_MOCK),
                    ethereum.Value.fromString("String"),
                ]),
            ])

already but it's not working. Any thoughts?

dimitrovmaksim commented 1 year ago

Try like this

let tupleArray: Array<ethereum.Value> = [ethereum.Value.fromAddress(FIRST_POOL_ADDRESS_MOCK), ethereum.Value.fromString("String")]
let tuple = changetype<ethereum.Tuple>(tupleArray)
let tupleValue = ethereum.Value.fromTuple(tuple)

...
.returns([tupleValue])
matstyler commented 1 year ago

@dimitrovmaksim not working

Unexpected error upon calling hook: Could not find a mocked function with the following parameters, address: 0x0000…0091, name: getPool, signature getPool(address,uint256):((address,string)), params: [Address(0x0000000000000000000000000000000000577791), Uint(2)].

Here is the whole mock:

createMockedFunction(
            addressMock,
            "getPool",
            "getPool(address,uint256):((address,string))"
        )
            .withArgs([
                ethereum.Value.fromAddress(PRINCIPAL_TOKEN_ADDRESS_MOCK),
                ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(2)),
            ])
            .returns([tupleValue])
dimitrovmaksim commented 1 year ago

Hm, are you sure your arguments are correct, this example works for me

  test("Can mock function that returns tuple", () => {
    let tupleArray: Array<ethereum.Value> = [ethereum.Value.fromAddress(Address.fromString("0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7")), ethereum.Value.fromString("string value")]
    let tuple = changetype<ethereum.Tuple>(tupleArray)
    let tupleValue = ethereum.Value.fromTuple(tuple)

    createMockedFunction(Address.fromString("0x90cBa2Bbb19ecc291A12066Fd8329D65FA1f1947"), "funcName", "funcName():((address, string))")
      .withArgs([])
      .returns([tupleValue])
    let val = ethereum.call(new ethereum.SmartContractCall("conName", Address.fromString("0x90cBa2Bbb19ecc291A12066Fd8329D65FA1f1947"), "funcName", "funcName():((address, string))", []))![0]

    assert.equals(tupleValue, val)
  })
matstyler commented 1 year ago

Hm, are you sure your arguments are correct, this example works for me

  test("Can mock function that returns tuple", () => {
    let tupleArray: Array<ethereum.Value> = [ethereum.Value.fromAddress(Address.fromString("0x89205A3A3b2A69De6Dbf7f01ED13B2108B2c43e7")), ethereum.Value.fromString("string value")]
    let tuple = changetype<ethereum.Tuple>(tupleArray)
    let tupleValue = ethereum.Value.fromTuple(tuple)

    createMockedFunction(Address.fromString("0x90cBa2Bbb19ecc291A12066Fd8329D65FA1f1947"), "funcName", "funcName():((address, string))")
      .withArgs([])
      .returns([tupleValue])
    let val = ethereum.call(new ethereum.SmartContractCall("conName", Address.fromString("0x90cBa2Bbb19ecc291A12066Fd8329D65FA1f1947"), "funcName", "funcName():((address, string))", []))![0]

    assert.equals(tupleValue, val)
  })

You are right, this solution works. I had a missing relation in between. Thank you!

valle-xyz commented 1 year ago

Thanks for this! This should go to the docs. :-)