上传到S3的aws-sdk在KOA中有效,但在通过Mocha

时间:2016-05-15 17:28:47

标签: node.js amazon-s3 mocha koa

我需要从koa上传一个文件到s3,我对koa很新,可能会遗漏一些明显的东西。它实际上完成了200,但文件从未出现在s3。

这是我的app.js片段:

'use strict';

var jwt = require('koa-jwt');


var bodyParser = require('koa-bodyparser');
var koaBody = require('koa-body');

const app = module.exports = require('koa')()
  .use(koaBody({multipart:true})) // this is to pase only multipart forms
  .use(require('./routes/common'))
  .use(require('./routes/auth'))
  .use(require('./routes/users_public'))
  .use(jwt({ secret: SECRET }))
  //protected routes below this line
  .use(require('./routes/subcontractors_private'))

  .listen(process.env.PORT || 3000);

subcontractors_private.js如下所示:

'use strict';

var AWS = require('aws-sdk');
var fs = require('fs');
var zlib = require('zlib');


var S3_BUCKET = require('../consts').S3_BUCKET;
var S3_OPTIONS = require('../consts').S3_OPTIONS;


module.exports = require('koa-router')()

.post('/subcontractors/:subcontractor_id/coi', function *(next) {
  var body = JSON.stringify(this.request.body, null, 2)

  let subcontractor_id = this.params.subcontractor_id;
  var file = this.request.body.files.coi.path;
  var body = fs.createReadStream(file).pipe(zlib.createGzip());


  var s3obj = new AWS.S3(
  {params:
    {
      Bucket: 'coi-test',
      Key: 'i/' + subcontractor_id + '.png.zgip'
    }
  });        

  s3obj.upload({Body: body})
    .on('httpUploadProgress', function(evt) {
      console.log(evt);
    })
    .send(function(err, data) {
      console.log(err, data);
    });


  this.response.status = 200;
  this.body = { "result": "subcontractor CIO successfully uploaded"};
  })
  .routes();

最后,来自测试文件夹的subcontractor_private.js的片段:

'use strict';

const supertest = require('co-supertest'); // SuperAgent-driven library for testing HTTP servers
const expect    = require('chai').expect;  // BDD/TDD assertion library
require('co-mocha');                     // enable support for generators in mocha tests using co
var uuid = require('uuid');

var db = require('../../consts').DB;
var moment = require('moment');

const app = require('../../app.js');

const request = supertest.agent(app.listen());

var assert = require('assert');

describe('/subcontractors private routes testing', function() {

  it.only('should be able to upload COI for subcontractor', function*() {

    const coi_expires_at = moment().add(1, 'd').format();
    const response =
      yield request.post('/subcontractors')
    .set('Content-Type', 'application/json')
    .set('Authorization', 'Bearer ' + token)
    .send({name: "Joe Doh"})
    .end();

    //now try to upload the coi file
    const response1 =
    yield request.post('/subcontractors/' + response.body.subcontractor.id + "/coi")
    .set('Authorization', 'Bearer ' + token)
    .field('Content-Type', 'multipart/form-data')
    .field('coi_expires_at', coi_expires_at)
    .attach('coi', './assets/logo-big.png')
    .end();

    expect(response1.status).to.equal(200, response1.text);
    expect(response1.body).to.be.an('object');
    expect(response1.body).to.be.json;
    expect(response1.body).to.contain.keys('result');
    expect(response1.body.result).to.equal('subcontractor CIO successfully uploaded');

  });
});

我尝试将上传代码作为独立的js文件(通过节点运行),它运行正常。但是,当我从mocha测试中将其作为节点应用程序运行时 - 该方法以响应200完成,并且永远不会完成上载。我做错了什么?

1 个答案:

答案 0 :(得分:1)

问题在于这种东西的异步性质。测试完成,无需等待请求完成(甚至正确启动)。 我并不完全清楚如何正确地做到这一点,但加上这个:

  it.only('should be able to upload COI for subcontractor', function*(done) {

(完成回调参数)使测试等待"完成"要调用的回调,从而允许aws sdk完成请求。但是,我不确定如何修复您的测试,因为这是两次异步。 koa服务器中的控制器方法异步返回,没有等待S3请求完成,因此mocha测试无法等待S3处理完成。

(另见我的相关问题: aws-sdk s3 upload not working from mocha test