7

I just started to learn do test with supertest and mocha. I've read the api document of supertest and it said that supertest support all lower-level API provided by superagent. SuperAgent said we can send a formData object by:

request.post('/user')
    .send(new FormData(document.getElementById('myForm')))
    .then(callback)

But when I try to send a formData object with supertest like this:

server
    .post('/goal_model/images/' + userId + '/' + tmid)
    .set('Authorization',`Bearer ${token}`)
    .send(formData)
    .expect("Content-type",/json/)
    .expect(201)
    .end(function(err,res){
         should(res.status).equal(201);
         console.log(res.message);
         done();
    });

Where the formData is like:

let file;
let formData = new FormData();
let fn = "../../../Downloads/Images/5k.jpg";
formData.append("image", file);

Then when I try to send this object it just said:

TypeError: "string" must be a string, Buffer, or ArrayBuffer

Does it possible to send a formData object in this way? What did I do wrong or how to do that? If not, why? I've searched many relative questions but none can solve my problem. I'm really in struglling now.

Feng Zhao
  • 71
  • 1
  • 3

1 Answers1

2

You can use .attach() method of supertest to send your file to the server. Function signature of .attach:

attach(field: string, file: MultipartValueSingle, options?: string | { filename?: string; contentType?: string }): this;

The data type of file parameter can be:

type MultipartValueSingle = Blob | Buffer | fs.ReadStream | string | boolean | number;

Here I pass a file path to .attach method.

E.g.

server.ts:

import express from 'express';
import multer from 'multer';
import path from 'path';

const app = express();
const port = 3000;
const upload = multer({ dest: path.resolve(__dirname, 'uploads/') });
app.post('/upload', upload.single('avatar'), (req, res) => {
  console.log('file:', req.file);
  console.log('content-type:', req.get('Content-Type'));
  res.sendStatus(200);
});

if (require.main === module) {
  app.listen(port, () => {
    console.log(`HTTP server is listening on http://localhost:${port}`);
  });
}

export { app };

server.test.ts:

import { app } from './server';
import request from 'supertest';
import path from 'path';

describe('52359964', () => {
  it('should pass', () => {
    return request(app)
      .post('/upload')
      .attach('avatar', path.resolve(__dirname, './downloads/5k.jpg'))
      .expect(200);
  });
});

integration test results:

  52359964
file: { fieldname: 'avatar',
  originalname: '5k.jpg',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  destination:
   '/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/52359964/uploads',
  filename: '329756ab22bf7abe2d27866a322c2f30',
  path:
   '/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/stackoverflow/52359964/uploads/329756ab22bf7abe2d27866a322c2f30',
  size: 0 }
content-type: multipart/form-data; boundary=--------------------------777489367435889931561092
    ✓ should pass (42ms)


  1 passing (48ms)
Lin Du
  • 88,126
  • 95
  • 281
  • 483