【问题标题】:Mock a multipart/form-data Express.JS request object模拟 multipart/form-data Express.JS 请求对象
【发布时间】:2017-01-12 05:03:53
【问题描述】:

我想对 Express 中间件函数进行单元测试,该函数又使用 node-formidable 处理分段文件上传。

这是一个人为的例子:

function doUpload(req, res, next) {
    const form = new formidable.IncomingForm();
    form.uploadDir = this.mediaDir;
    form.keepExtensions = true;
    form.type = 'multipart';
    form.multiples = true;

    form.parse(req, function(err, fields, files) {
        res.writeHead(200, {'content-type': 'text/plain'});
        res.write('received upload:\n\n');
        res.end(util.inspect({fields: fields, files: files}));
    });
}

在使用 Chrome 和正在运行的 Express 应用程序进行测试时,此代码适用于我。

我希望我的测试代码如下所示,我正在模拟请求对象,但我不知道如何使用表单数据模拟请求对象。强大的回调没有触发:

it(‘handles uploads’, (done) => {
    const mockReq = http.request({
        host: 'example.org',
    });
    mockReq.url = ‘/upload’;

    const res = jasmine.createSpyObj('response', [ 'json', 'send', 'status', 'render', 'header', ‘redirect’, ‘end’, ‘write;]);
    const next = jasmine.createSpy('next');

    //*how to emulate a request with a multipart file upload)

    doUpload(req, res, next);
    res.write.and.callFake(done);
});

我尝试使用 form-data 库创建一个 FormData 对象并将其通过管道传递给请求,但没有成功,我不确定我是否走在正确的轨道上。像这样的:

var form = new FormData();

const buff = fs.readFileSync(path.join(__dirname, '../fixtures/logo.png'));

form.append('file', buff, {
    filename: 'logo.jpg',
    contentType: 'image/png',
    knownLength: buff.length
});
form.append('name', 'Logo');

req.headers = form.getHeaders();

form.pipe(req);
doUpload(req, res, next);

【问题讨论】:

  • 同样的问题,我试图模拟一个包含表单数据的请求。
  • 我也遇到了这种方法的问题,但是我发现在创建模拟请求时我缺少 HTTP POST 方法。一旦解决了这个问题,它就会成为一种魅力

标签: node.js unit-testing express jasmine formidable


【解决方案1】:

您可以使用像supertest 这样的请求测试器来执行此操作。这是一个示例,假设您的主文件名为 app.js:

const request = require('supertest');
const app = require('app.js');

it('Uploads a file', function(){
    request(app)
      .post('/upload')
      .field('name', 'Logo') //adds a field 'name' and sets its value to 'Logo'
      .attach('file', '/path/to/file') // attaches the file to the form
      .then(function(response){
          // response from the server
          console.log(response.status);
          console.log(response.body);
      })

})

【讨论】:

  • 对 Http 端点进行单元测试的好建议。 Supertest真的很容易使用。说这也支持 async/await 语法可能有用
【解决方案2】:

使用form-datamock-express-request 的组合。这对我有用:

const fs = require('fs');
const MockExpressRequest = require('mock-express-request');
const FormData = require('form-data');

const form = new FormData();
form.append('my_file',
  fs.createReadStream(path.join(__dirname, 'fixtures', 'file-upload-test.txt'))
);
const request = new MockExpressRequest({
  method: 'POST',
  host: 'localhost',
  url: '/upload',
  headers: form.getHeaders()
});

form.pipe(request);
doUpload(request, response, next);

【讨论】:

  • 很棒的建议,这是一种非常有用的方法来测试使用来自标准库或 express 的 Http 请求的实用程序函数,从而避免需要进行 Http 调用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多