Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock multer with supertest?

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?

like image 632
aprisniak Avatar asked Oct 31 '17 17:10

aprisniak


People also ask

How do you mock multer in jest?

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 .

Why multer is used in Node js?

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.

What is upload single in multer?

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.

What is multer middleware?

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 ).


2 Answers

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();
            };
          },
        };
      },
);
like image 76
Ridwan Taiwo Avatar answered Sep 19 '22 17:09

Ridwan Taiwo


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();
      };
    },
  };
});

.
.
.

like image 27
ganesh kathar Avatar answered Sep 16 '22 17:09

ganesh kathar