aws-sdk上传到S3在KOA中工作,但在通过Mocha调用时停止工作

我需要从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(); 

最后,testing文件夹中的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文件(通过节点运行),它工作正常。 但是,当我作为一个节点的应用程序从摩卡testing运行它 – 该方法完成响应200,并永远不会完成上传。 我究竟做错了什么?

问题是这种东西的asynchronous性质。 testing结束,不等待请求完成(甚至正常启动)。 我不完全清楚如何正确地做到这一点,但增加了这一点:

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

(完成callback参数)使得testing等待“完成”callback被调用,从而允许aws sdk完成请求。 我不知道如何解决你的testing,但是,因为这是两次asynchronous。 您的koa服务器中的控制器方法asynchronous返回而不等待S3请求完成,所以摩卡testing无法等待S3处理完成。

(也见我的相关问题: aws-sdk s3上传不工作,从摩卡testing )