为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

猛跑小猪 2021-06-30 14:59:21
请允许我注意,可以在此处找到与此类似的问题,但已接受的答案的解决方案对我不起作用。还有一个与此类似的问题,其答案建议直接操作函数的原型,但这同样没有结果。我正在尝试使用 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.jsmodule.exports = jest.genMockFromModule('sharp');结果Error: Maximum Call Stack Size Exceeded尝试二// __mocks__/sharp.jsmodule.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,但他们似乎也没有完成工作。
查看完整描述

1 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

您的第二次尝试非常接近。


唯一能与它的问题是,每次sharp被称为一个新的嘲笑对象返回新的resize,jpeg和toBuffer模拟功能...


...这意味着当你这样测试时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);


查看完整回答
反对 回复 2021-07-01
  • 1 回答
  • 0 关注
  • 184 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信