如何使用开玩笑介绍异步函数?

发布于 2025-02-13 18:06:19 字数 2968 浏览 0 评论 0原文

我要测试的功能接收到异步函数作为参数。在我的参数验证中,我验证它是否存在,是一个函数,并且是这样的异步函数:

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 ..
}

我对上述代码的测试看起来像这样:

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()
    })
})

现在,我想测试是否通过在模拟上监视模拟,因此,我正在尝试在测试的顶部执行此操作:

mockAsyncConsumerFunction = async (recordBody) => `${recordBody} - resolved consumer`
mockAsyncConsumerFunctionSpy = jest.fn(mockAsyncConsumerFunction)

然后使用.mocks对象在jest.fn上使用标准断言,如下:

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})
})

不幸,不幸的是,做完之后这是我的测试失败,因为它不再被视为异步函数,因此我的输入验证失败了,给了我:

FUNCTION: consumeRecords › calls consumer function correct number of
 times

    Argument, consumerFunction, is not a async function in consumeRecords function.

如何在Jest中制作一个模拟/间谍功能,读起来是异步函数?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文