The function I'm looking to test receives a async function as an argument. In my argument validation I verify that it exists, is a function, and is an async function like so:
exports.consumeRecords = async (consumerFunction, records) => {
    if (!consumerFunction) {
        throw new Error(`Missing required argument, consumerFunction, in consumeRecords function`)
    }
    if (typeof consumerFunction !== 'function') {
        throw new Error(`Argument, consumerFunction, is not of type 'function' in consumeRecords function.  Type found: ${typeof consumerFunction}`)
    }
    if (args.consumerFunction.then instanceof Promise) {
        throw new Error(`Argument, consumerFunction, is not a async function in consumeRecords function.`)
    }
    await consumerFunction(records)
// ... blah blah ..
}
My tests for the above code look like this:
describe('FUNCTION: consumeRecords', () => {
    let logSpy, mockAsyncConsumerFunction
    beforeEach(()=> {
        mockAsyncConsumerFunction = async (recordBody) => `${recordBody} - resolved consumer`
        logSpy = jest.spyOn(console, 'log').mockImplementation(() => null)
    })
        test('throws error when missing consumerFunction argument', async () => {
            await expect(async () => await utils.consumeRecords({})).rejects.toThrow(`Missing required argument, consumerFunction,`)
        })
        test('throws error when consumerFunction is not a function', async () => {
            await expect(async () => await utils.consumeRecords({ consumerFunction: 123 })).rejects.toThrow(`Argument, consumerFunction, is not of type 'function'`)
        })
        test('throws error when consumerFunction is not async function', async () => {
            let syncFunction = () => console.log()
            await expect(async () => await utils.consumeRecords({ consumerFunction: syncFunction })).rejects.toThrow(`Argument, consumerFunction, is not a async function`)
        })
    afterEach(() => {
        jest.clearAllMocks()
    })
    afterAll(() => {
        jest.restoreAllMocks()
    })
})
Now, I'd like to test if consumerFunction gets called by spying on the mock, so I'm trying to do this at the top of my test:
mockAsyncConsumerFunction = async (recordBody) => `${recordBody} - resolved consumer`
mockAsyncConsumerFunctionSpy = jest.fn(mockAsyncConsumerFunction)
and then the standard assertions using the .mocks object on the jest.fn, like this:
test('calls consumer function correctly', async () => {
    await utils.consumeRecords({ consumerFunction: mockAsyncConsumerFunctionSpy, records: [{ body: JSON.stringify({fake:111}) },{ body: JSON.stringify({fake:222}) }], taskNameString: "Apply image overlays" })
    expect(mockAsyncConsumerFunctionSpy).toHaveBeenCalledWith({fake:111})
})
Unfortunately, after doing this, my test fails because it's no longer seen as an async function and thus my input validation fails, giving me:
FUNCTION: consumeRecords › calls consumer function correct number of
 times
    Argument, consumerFunction, is not a async function in consumeRecords function.
How can I make a mock/spy function in Jest that reads as an async function?
