dimanche 4 septembre 2016

Mock a multipart/form-data Express.JS request object

I would like to unit test an Express middleware function which, in turn, uses node-formidable to process a multipart file upload.

Here’s a contrived example:

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}));
    });
}

This code works for me when tested with Chrome and a running Express app.

I want my test code to look like the following where I am mocking the request object, but I can't figure out how to mock the request object with the form data. The formidable callback is not firing:

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);
});

I’ve tried using the form-data library to create a FormData object and pipe it to the request, but no luck, I’m not sure if I’m on the right track or way off. Something like this:

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);

Aucun commentaire:

Enregistrer un commentaire