我需要从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完成,并且永远不会完成上载。我做错了什么?
答案 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)