Allow me to note that a similar question to this one can be found here, but the accepted answer's solution did not work for me. There was another question along the same lines, the answer of which suggested to directly manipulate the function's prototypes, but that was equally non-fruitful.
I am attempting to use Jest to mock this NPM Module, called "sharp". It takes an image buffer and performs image processing/manipulation operations upon it.
The actual implementation of the module in my codebase is as follows:
const sharp = require('sharp');
module.exports = class ImageProcessingAdapter {
async processImageWithDefaultConfiguration(buffer, size, options) {
return await sharp(buffer)
.resize(size)
.jpeg(options)
.toBuffer();
}
}
You can see that the module uses a chained function API, meaning the mock has to have each function return this
.
The Unit Test itself can be found here:
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);
});
Below are my attempts at mocking:
Attempt One
// __mocks__/sharp.js
module.exports = jest.genMockFromModule('sharp');
Result
Error: Maximum Call Stack Size Exceeded
Attempt Two
// __mocks__/sharp.js
module.exports = jest.fn().mockImplementation(() => ({
resize: jest.fn().mockReturnThis(),
jpeg: jest.fn().mockReturnThis(),
toBuffer:jest.fn().mockReturnThis()
}));
Result
Expected mock function to have been called with:
[{"height": 10, "width": 10}]
But it was not called.
Question
I would appreciate any aid in figuring out how to properly mock this third-party module such that I can make assertions about the way in which the mock is called.
I have tried using sinon
and proxyquire
, and they don't seem to get the job done either.
Reproduction
An isolated reproduction of this issue can be found here.
Thanks.
Allow me to note that a similar question to this one can be found here, but the accepted answer's solution did not work for me. There was another question along the same lines, the answer of which suggested to directly manipulate the function's prototypes, but that was equally non-fruitful.
I am attempting to use Jest to mock this NPM Module, called "sharp". It takes an image buffer and performs image processing/manipulation operations upon it.
The actual implementation of the module in my codebase is as follows:
const sharp = require('sharp');
module.exports = class ImageProcessingAdapter {
async processImageWithDefaultConfiguration(buffer, size, options) {
return await sharp(buffer)
.resize(size)
.jpeg(options)
.toBuffer();
}
}
You can see that the module uses a chained function API, meaning the mock has to have each function return this
.
The Unit Test itself can be found here:
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);
});
Below are my attempts at mocking:
Attempt One
// __mocks__/sharp.js
module.exports = jest.genMockFromModule('sharp');
Result
Error: Maximum Call Stack Size Exceeded
Attempt Two
// __mocks__/sharp.js
module.exports = jest.fn().mockImplementation(() => ({
resize: jest.fn().mockReturnThis(),
jpeg: jest.fn().mockReturnThis(),
toBuffer:jest.fn().mockReturnThis()
}));
Result
Expected mock function to have been called with:
[{"height": 10, "width": 10}]
But it was not called.
Question
I would appreciate any aid in figuring out how to properly mock this third-party module such that I can make assertions about the way in which the mock is called.
I have tried using sinon
and proxyquire
, and they don't seem to get the job done either.
Reproduction
An isolated reproduction of this issue can be found here.
Thanks.
Share Improve this question asked Jun 13, 2019 at 23:38 user6233283user62332831 Answer
Reset to default 8Your second attempt is really close.
The only issue with it is that every time sharp
gets called a new mocked object is returned with new resize
, jpeg
, and toBuffer
mock functions...
...which means that when you test resize
like this:
expect(sharp().resize).toHaveBeenCalledWith(size);
...you are actually testing a brand new resize
mock function which hasn't been called.
To fix it, just make sure sharp
always returns the same mocked object:
__mocks__/sharp.js
const result = {
resize: jest.fn().mockReturnThis(),
jpeg: jest.fn().mockReturnThis(),
toBuffer: jest.fn().mockReturnThis()
}
module.exports = jest.fn(() => result);