I have an app built on Express.js and I\'d like to test the file upload functionality. I\'m trying to reproduce the object parsed to req.files (when using express.bodyParser
Changing attach('image') to attach('file') will solve the problem of req.files.file not defined.
var should = require('should'),
supertest = require('supertest');
var request = supertest('localhost:3000');
describe('upload', function() {
it('a file', function(done) {
request.post('/your/endpoint')
.field({field1: 'xxx', field2: 'yyy'})
.attach('file', 'path/to/file.jpg')
.end(function(err, res) {
res.should.have.status(200) // 'success' status
done()
});
});
});
You might try using zombie.js https://github.com/assaf/zombie , it creates a virtual browser for testing with basic functionality. It can attach a file to a specific input field and supports cookies and sessions
related gist : https://gist.github.com/764536
If using request promise you can simply do this, sending formData is built into it:
var options = {
method: 'POST',
uri: base + '/api/image/upload',
formData: {
someField: 'someValue',
anotherField: 'anotherValue',
file: {
// path to image
value: fs.createReadStream('./testImg.png'),
options: {
filename: 'testImg.png',
contentType: 'image/png'
}
}
}
};
let resp;
try {
resp = await request.post(options);
body = JSON.parse(resp);
} catch (e) {
console.log(e);
resp = e.response;
code = resp.statusCode;
body = JSON.parse(resp.body);
}
// access what is returned here, check what needs to be
assert.equal(code, 200, 'Status: ' + code + ': ' + body.error);
assert.equal(body.success, true);
assert.exists(body.image);
Just came across this module by TJ: https://github.com/visionmedia/supertest.
Here is an example of how you would do it with supertest module.
var should = require('should'),
supertest = require('supertest');
var request = supertest('localhost:3000');
describe('upload', function() {
it('a file', function(done) {
request.post('/your/endpoint')
.field('extra_info', '{"in":"case you want to send json along with your file"}')
.attach('image', 'path/to/file.jpg')
.end(function(err, res) {
res.should.have.status(200); // 'success' status
done();
});
});
});
You can do this directly in Mocha but it's a bit tricky. Here's an example posting an image:
var filename = 'x.png'
, boundary = Math.random()
request(app)
.post('/g/' + myDraftGallery._id)
.set('Content-Type', 'multipart/form-data; boundary=' + boundary)
.write('--' + boundary + '\r\n')
.write('Content-Disposition: form-data; name="image"; filename="'+filename+'"\r\n')
.write('Content-Type: image/png\r\n')
.write('\r\n')
.write(fs.readFileSync('test/'+filename))
.write('\r\n--' + boundary + '--')
.end(function(res){
res.should.have.status(200)
done()
})
The name parameter of Content-Disposition is what your file will be accessible as via req.files (so req.files.image for my example) You can also use an array value like this: name="images[]" and your file(s) will be available via an array, e.g: req.files.images[0]
Also if you're not already using it you should have a look at this (makes mocha/express testing a ~bit~ easier): https://github.com/visionmedia/express/blob/master/test/support/http.js
Edit: Since express 3-beta5, express uses supertest. To look at the old http.js code look here: https://github.com/visionmedia/express/blob/3.0.0beta4/test/support/http.js Or simply move over to supertest..