使用mulipart / form-data的Mocha测试帖请求不起作用

时间:2016-01-22 04:46:51

标签: node.js mocha supertest

我正在尝试使用mocha测试发布请求,并且发布请求正文包含图像字段以及json数据。当图像与json一起附加时,测试不会执行。并且测试正在执行,但在没有附件的情况下引发400错误在这里附上我的代码。

var request = require('supertest');
var app = require('../server')

request(app).post('/companies/')
           .set({apikey: 'TestHashKey',
               'app-token': process.env.API_TOKEN,
               'app-key': process.env.API_KEY})
           .field('Content-Type', 'multipart/form-data')
           .field('name', 'sample_companyx')
           .field('phoneNumber','+963014311354')
           .attach('logo', '/app/test/images/test_logo.jpg')
           .expect(200)
           .end(function (err, res) {
                if (err) {
                    throw err;
                }
                done();
                });

没有附件的回复正在下面粘贴,

  

POST / companies / 400 12ms - 12b   回复缺少徽标   2016-01-22T04:08:20.044Z - 错误:星期五,22一月2016 04:08:20 GMT uncaughtException:预计200“OK”,得到400“Bad Request”

附件存在时的响应是

  

2016-01-22T04:13:44.849Z - 信息:[...]公司API在端口4000上启动并运行   2016-01-22T04:13:45.916Z - 信息:公司工人准备好了!   错误的ERR!测试失败。请参阅上文了解更多详情。   错误的ERR!不好的代码0

2 个答案:

答案 0 :(得分:0)

这是一个最小的工作示例:

app.js

const express = require("express");
const multer = require("multer");
const path = require("path");
const crypto = require("crypto");
const app = express();

const storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, path.resolve(__dirname, "uploads/"));
  },
  filename: function(req, file, cb) {
    crypto.pseudoRandomBytes(16, function(err, raw) {
      if (err) return cb(err);

      cb(null, raw.toString("hex") + path.extname(file.originalname));
    });
  },
});
const upload = multer({ storage });

app.post("/companies/", upload.single("logo"), (req, res) => {
  console.log("req.body: ", req.body);
  console.log("req.file:", req.file);
  res.sendStatus(200);
});

module.exports = app;

app.test.js

const app = require("./app");
const request = require("supertest");
const path = require("path");

describe("34939199", () => {
  it("should pass", (done) => {
    process.env.API_TOKEN = "123";
    process.env.API_KEY = "abc";
    request(app)
      .post("/companies/")
      .set({ apikey: "TestHashKey", "app-token": process.env.API_TOKEN, "app-key": process.env.API_KEY })
      .field("Content-Type", "multipart/form-data")
      .field("name", "sample_companyx")
      .field("phoneNumber", "+963014311354")
      .attach("logo", path.resolve(__dirname, "fixtures/test_logo.jpg"))
      .expect(200)
      .end(function(err, res) {
        if (err) {
          throw err;
        }
        done();
      });
  });
});

具有覆盖率报告的集成测试结果:

 34939199
req.body:  [Object: null prototype] {
  'Content-Type': 'multipart/form-data',
  name: 'sample_companyx',
  phoneNumber: '+963014311354' }
req.file: { fieldname: 'logo',
  originalname: 'test_logo.jpg',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  destination:
   '/Users/ldu020/workspace/github.com/mrdulin/mocha-chai-sinon-codelab/src/stackoverflow/34939199/uploads',
  filename: 'da39e06c1cd2a97f98a66eb6d832aa74.jpg',
  path:
   '/Users/ldu020/workspace/github.com/mrdulin/mocha-chai-sinon-codelab/src/stackoverflow/34939199/uploads/da39e06c1cd2a97f98a66eb6d832aa74.jpg',
  size: 0 }
    ✓ should pass (50ms)


  1 passing (56ms)

-------------|----------|----------|----------|----------|-------------------|
File         |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------|----------|----------|----------|----------|-------------------|
All files    |     93.1 |       50 |      100 |    96.43 |                   |
 app.js      |    94.12 |       50 |      100 |      100 |                13 |
 app.test.js |    91.67 |       50 |      100 |    91.67 |                20 |
-------------|----------|----------|----------|----------|-------------------|

文件夹结构:

.
├── app.js
├── app.test.js
├── fixtures
│   └── test_logo.jpg
└── uploads
    └── da39e06c1cd2a97f98a66eb6d832aa74.jpg

2 directories, 4 files

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/34939199

答案 1 :(得分:0)

上述解决方案(虽然有助于查看)对我不起作用,因为 req.file 或 req.files 在复制解决方案时没有任何信息。

如果有人仍在寻找解决方案,我使用“form.parse”作为后端(nodejs)上多方库的一部分从 req 获取文件对象,这让我永远意识到文件已存储在“文件”的附件字段中,如下所示。

exports.nodeFunction = function (req, res) {
    var form = new multiparty.Form({
        uploadDir: 'app/tmp'
    });
    form.parse(req, function (err, fields, files) { //https://www.npmjs.com/package/multiparty
        var file = files.file ? files.file[0] : files.attachment[0]; 
        // when uploaded on front end, files.file has the file, but files.attachment holds the file when using supertest in mocha. 
    });

这也是我的测试函数:

        describe('POST', function () {
            it('Should upload file', async function () {
                    const res = await request(app).post(url) // request = require('supertest') 
                    .attach('attachment', path.resolve(__dirname, filename)) // using "path" library 
                    .expect(200) 
            });
        });