在 Node 中用 Jest 模拟一个使用链式函数调用的 Node 模块

请允许我注意,可以在此处找到与此类似的问题,但已接受的答案的解决方案对我不起作用。还有一个与此类似的问题,其答案建议直接操作函数的原型,但这同样没有结果。


我正在尝试使用 Jest 来模拟这个名为“sharp”的 NPM 模块。它需要一个图像缓冲区并对其执行图像处理/操作操作。


该模块在我的代码库中的实际实现如下:


const sharp = require('sharp');


module.exports = class ImageProcessingAdapter {

    async processImageWithDefaultConfiguration(buffer, size, options) {

        return await sharp(buffer)

            .resize(size)

            .jpeg(options)

            .toBuffer();

    }

}

您可以看到该模块使用了一个链式函数 API,这意味着模拟必须让每个函数 return this。


单元测试本身可以在这里找到:


jest.mock('sharp');

const sharp = require('sharp');


const ImageProcessingAdapter = require('./../../adapters/sharp/ImageProcessingAdapter');


test('Should call module functions with correct arguments', async () => {

    // Mock values

    const buffer = Buffer.from('a buffer');

    const size = { width: 10, height: 10 };

    const options = 'options';


    // SUT

    await new ImageProcessingAdapter().processImageWithDefaultConfiguration(buffer, size, options);


    // Assertions

    expect(sharp).toHaveBeenCalledWith(buffer);

    expect(sharp().resize).toHaveBeenCalledWith(size);

    expect(sharp().jpeg).toHaveBeenCalledWith(options);

});

以下是我在嘲讽方面的尝试:


尝试一

// __mocks__/sharp.js

module.exports = jest.genMockFromModule('sharp');

结果

Error: Maximum Call Stack Size Exceeded

尝试二

// __mocks__/sharp.js

module.exports = jest.fn().mockImplementation(() => ({

    resize: jest.fn().mockReturnThis(),

    jpeg: jest.fn().mockReturnThis(),

    toBuffer:jest.fn().mockReturnThis()

}));

结果

Expected mock function to have been called with:

      [{"height": 10, "width": 10}]

But it was not called.

问题

我很感激在弄清楚如何正确模拟这个第三方模块方面的任何帮助,以便我可以对调用模拟的方式做出断言。


我试过使用sinonand proxyquire,但他们似乎也没有完成工作。


猛跑小猪
浏览 185回答 1
1回答

墨色风雨

您的第二次尝试非常接近。唯一能与它的问题是,每次sharp被称为一个新的嘲笑对象返回新的resize,jpeg和toBuffer模拟功能......这意味着当你这样测试时resize:expect(sharp().resize).toHaveBeenCalledWith(size);...您实际上是在测试一个resize尚未调用的全新模拟函数。要修复它,只需确保sharp始终返回相同的模拟对象:__mocks__/sharp.jsconst result = {  resize: jest.fn().mockReturnThis(),  jpeg: jest.fn().mockReturnThis(),  toBuffer: jest.fn().mockReturnThis()}module.exports = jest.fn(() => result);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript