I'm writing file upload API and have some troubles with mocking multer. I'm trying to test my endpoint with supertest.
it('load image', async () => {
await app
.post(`${apiImage}`)
.set('Authorization', 'abc123')
.attach('avatar', `${__dirname}/test.jpg`);
.expect(200);
});
Upload works as expected. But every time when I run test, new file being created. So, how to mock multer and does not create new file every time?
When you use jest. mock('multer') , Jest automatically mocks the module and returns undefined when it gets called in the test. Since we want to mock memoryStorage and any methods as well, we have to do it explicitly by passing a factory as the second argument to jest. mock .
As mentioned previously, Multer is a Node. js middleware used for handling multipart/form-data, which is primarily used for uploading files. For those who don't know what a middleware is in Node. js, it's a function that receives the request and response object when a user from the client-side makes any request.
Multer supports uploading a single file as well as multiple files. In this case, we have used multer({..}). single() which is used for uploading a single file. As I have mentioned before that the multer adds a file object to the request. The file object contains metadata related to the file.
Multer is a node. js middleware for handling multipart/form-data , which is primarily used for uploading files. It is written on top of busboy for maximum efficiency. NOTE: Multer will not process any form which is not multipart ( multipart/form-data ).
I had a middleware helper to wrap multer like this
// middleware/index.js
const multer = require('multer');
exports.multerUpload = () => multer({...});
Then use it in my routes like so
// routes.js
const { multerUpload } = require('path/to/middlewares');
app.post('/upload', multerUpload().any());
Then, in my tests, I can stub out multerUpload
// test.js
const middlewares = require('path/to/middlewares');
sinon.stub(middlewares, 'multerUpload').callsFake(
() => {
return {
any() {
return (req, res, next) => {
// You can do whatever you like to the request body here e.g
req.body = { title: req.query.title };
req.files = [{ location: 'sample.url', key: 'sample.key' }];
return next();
};
},
};
},
);
Mock Multer using Jest (Similar to above ans but using Jest)
App.js
Used multer as middleware
const app = express();
app.use()
app.use(multer({ dest: FILE_UPLOAD_PATH }).single('datafile'));
app.use('/api', apiRoutes);
apiRoute.js
router.post('/datasources', async function (req, res) {
...
});
apiRoute.test.js
const multer = require('multer');
jest.mock('multer');
multer.mockImplementation(() => {
return {
single() {
return (req, res, next) => {
req.body = { title: req.query.title };
req.file = [{ originalname: 'sample.name', mimetype: 'sample.type', path: 'sample.url' }];
return next();
};
},
};
});
.
.
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With