Search code examples
javascriptunit-testingjestjsweb3js

How to mock a function returned by a mocked function


I am trying to write mock a test for the following function call

const contract = await new web3.eth.Contract();

tx.data = await contract.methods
  .setup(
    [juryAddress, buyerAddress, sellerAddress],
    threshold,
    to,
    txData,
    fallbackHandler,
    paymentToken,
    0,
    sellerAddress
  )
  .encodeABI();

I am trying to mock this as a function contract.methods.setup() that returns a function object encodeABI() which then returns a dummy value {}.

The mock I am trying looks like this, although it is not working

const encodeABI = jest.fn()
encodeABI.mockReturnValue({})

const contract = {
    methods: {
        setup: jest.fn(),
    }
}

eth.Contract.mockResolvedValue(contract)
contract.methods.setup.mockResolvedValue(encodeABI)
expect(encodeABI).toBeCalled()

expect(encodeABI).toBeCalled() is not being called as I expect


Solution

  • Your production code awaits encodeABI(), not setup(). It expects setup() to return an object with an encodeABI() function, not a Promise.

    I would recommend making the following changes

    const encodeABI = jest.fn(async () => ({})) // return a Promise here
    
    const contract = {
        methods: {
            setup: jest.fn(() => ({ encodeABI })) // return an object with encodeABI
        }
    }