在Node中模拟使用链式函数调用和Jest的Node Module

时间:2019-06-13 23:38:32

标签: javascript node.js unit-testing mocking jestjs

让我注意到,可以找到与此问题类似的问题here,但是接受的答案的解决方案对我而言不起作用。同样,还有另一个问题,答案是直接操纵函数的原型,但这同样没有结果。

我正在尝试使用Jest模拟this NPM模块,称为“尖锐”。它需要一个图像缓冲区并对其执行图像处理/操作。

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

const sharp = require('sharp');

module.exports = class ImageProcessingAdapter {
    async processImageWithDefaultConfiguration(buffer, size, options) {
        return await sharp(buffer)
            .resize(size)
            .jpeg(options)
            .toBuffer();
    }
}

您可以看到该模块使用了链式函数API,这意味着模拟必须使每个函数返回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.

问题

在弄清楚如何正确模拟该第三方模块方面,我将不胜感激,这样我就可以断言模拟的调用方式。

我尝试使用sinonproxyquire,但它们似乎也无法完成任务。

复制

可以单独here找到此问题的复制品。

谢谢。

1 个答案:

答案 0 :(得分:2)

您的第二次尝试真的很接近。

唯一的问题是每次调用sharp时,都会使用新的resizejpegtoBuffer模拟函数返回一个新的模拟对象...

...这意味着当您像这样测试resize时:

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

...实际上,您正在测试一个尚未调用的全新resize模拟函数。

要解决此问题,只需确保sharp始终返回相同的模拟对象:

__ mocks __ / sharp.js

const result = {
  resize: jest.fn().mockReturnThis(),
  jpeg: jest.fn().mockReturnThis(),
  toBuffer: jest.fn().mockReturnThis()
}

module.exports = jest.fn(() => result);