让我注意到,可以找到与此问题类似的问题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.
在弄清楚如何正确模拟该第三方模块方面,我将不胜感激,这样我就可以断言模拟的调用方式。
我尝试使用sinon
和proxyquire
,但它们似乎也无法完成任务。
可以单独here找到此问题的复制品。
谢谢。
答案 0 :(得分:2)
您的第二次尝试真的很接近。
唯一的问题是每次调用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);