javascript - 在 Node 中使用 Jest 模拟使用链式函数调用的节点模块
问题描述
请允许我注意,可以在此处找到与此问题类似的问题,但接受的答案的解决方案对我不起作用。还有另一个问题,其答案建议直接操作函数的原型,但这同样没有结果。
我正在尝试使用 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,这意味着模拟必须让每个函数返回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.
问题
在弄清楚如何正确模拟此第三方模块以便我可以对调用模拟的方式做出断言时,我将不胜感激。
我试过使用sinon
and proxyquire
,他们似乎也没有完成工作。
再生产
可以在此处找到此问题的孤立复制。
谢谢。
解决方案
你的第二次尝试真的很接近。
唯一的问题是每次sharp
被调用时都会返回一个新的模拟对象,并带有 new resize
、jpeg
和toBuffer
mock 函数......
...这意味着当你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);
推荐阅读
- python-3.x - 使用python获取机器登录用户名
- c - float 到 int 的隐式转换和价值损失的可能性
- swift - 搜索后 UITableView 的错误单元格上的 Like 按钮
- unity3d - 如何在 Unity 中自动调整相交平面?
- java - 是数组列表
ArrayList 中包含Java 中其他类型的任何特殊内容? - python - 错误:(-215:断言失败)_src.total() > 0 in function 'cv::warpPerspective'
- javascript - 在 Vue + .Net 核心应用程序中对组件使用导入时出现“TypeError:“_Ctor”是只读的”
- r - 饼图中的错误(效果,col = rainbow()):“x”值必须为正
- java - 如果在 Rest Api 调用中没有从数据库中找到数据,则返回哪个 HTTP 状态代码
- c++ - 函数调用和函数定义中使用的参数的差异