Search code examples
javascriptnode.jsjestjsmultipartform-datasupertest

How to access .field values on Supertest


good evening.

I'm trying to create a POST request with a file and some data on a REST API I'm building using NodeJS. If not clear, my goal to this feature of the API is to save a register of a picture, so I'd like to send the picture file, the picture name and it's number on the same request.

I'm currently using Jest / supertest for testing and to test this specific functionality, I've tried the following:

    const response = await request(app)
      .post("/uploads/pics")
      .field("name", "PicureName")
      .field("number", "PictureNumber")
      .attach("file", picture);

I've read this from https://visionmedia.github.io/superagent/#multipart-requests

My problem is that I can't get the values of name and number on my request on my controller, so I can't use them to save the object.

I've tried many ways, such as:

req.body.name
req.name
req.field.name
req.query.name

but none of these worked for me.

I also tried printing the whole request, however I couldn't find anything related to name, number or field there.

Does anyone can tell what I'm doing wrong ?


Solution

  • You should use https://github.com/expressjs/multer middleware for handling file upload. Then, req.body will hold the text fields, if there were any.

    E.g.

    index.js:

    const express = require('express');
    const multer = require('multer');
    const app = express();
    
    const upload = multer({ dest: 'uploads/' });
    app.post('/uploads/pics', upload.single('file'), (req, res) => {
      console.log(req.body);
      console.log(req.file);
      res.sendStatus(200);
    });
    
    module.exports = app;
    

    index.test.js:

    const request = require('supertest');
    const app = require('./');
    const path = require('path');
    const { expect } = require('chai');
    
    describe('62862866', () => {
      it('should pass', async () => {
        const picture = path.resolve(__dirname, './test.jpg');
        const response = await request(app)
          .post('/uploads/pics')
          .field('name', 'PicureName')
          .field('number', 'PictureNumber')
          .attach('file', picture);
        expect(response.status).to.be.eq(200);
      });
    });
    

    integration test result:

      62862866
    [Object: null prototype] { name: 'PicureName', number: 'PictureNumber' }
    { fieldname: 'file',
      originalname: 'test.jpg',
      encoding: '7bit',
      mimetype: 'image/jpeg',
      destination: 'uploads/',
      filename: '181b96eb9044aac5d50c8c1e3159a120',
      path: 'uploads/181b96eb9044aac5d50c8c1e3159a120',
      size: 0 }
        ✓ should pass (84ms)
    
    
      1 passing (103ms)