Error analysis
The code generally works, and the problem is somewhere inside the superspy.
In fact, the question does not actually contain some details, so I had to guess the missing parts, for example, chai.request(app) is executed using chai-http , which in turn uses superagent to execute http requests.
And the problem seems to be somewhere inside the superspy, I was able to reproduce your error with a bit more information (not sure why I got a longer trace):
Uncaught SyntaxError: Unexpected token { at Object.parse (native) at IncomingMessage.<anonymous> (/project/path/node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js:9:2 at IncomingMessage.EventEmitter.emit (events.js:117:20) at _stream_readable.js:920:16 at process._tickCallback (node.js:415:13)
And I was able to verify that JSON parses is trying to parse the double answer. As with server responses with {} , the parser has {}{} or server responses with {"a":"b"} , the parser has {"a":"b"}{"a":"b"} . You can verify this yourself by inserting console.log(res.text) in front of this line (locally this file is under node_modules / chai-http / node_modules / superagent).
Also, if I move readStream.pipe(req); just above the line with var readStream :
var readStream = fs.createReadStream('./test.wav'); readStream.pipe(req); readStream.on('end',function(){ ...
Then the test passes, but outputs a "double callback!" - also printed by the superagent and confirms that something is wrong with him.
Correction
It's not difficult to do the same without chai-http and superagent .
Firstly, the server code. It has changed a bit - instead of clientRequest.on('end', ... I connect it to the write stream. This way I can also check if the file was really transferred:
var express = require('express'); var fs = require('fs'); var app = express(); module.exports = app; app.post('/speech', function (clientRequest, clientResponse) { console.log('speech'); var writeStream = fs.createWriteStream('./test_out.wav');
And the test:
var fs = require('fs'); var chai = require('chai'); var http = require('http'); // Require our application and create a server for it var app = require('./unexpected'); var server = http.createServer(app); server.listen(0); var addr = server.address(); describe('server', function() { this.timeout(10000); it('should WORK!!!"', function (done){ // setup read stream var readStream = fs.createReadStream('./test.wav'); readStream.on('end',function(){ console.log("readStream end>>>>>>>>>>>>>>>>>>>>>>"); }); // setup the request var request = http.request({ 'host': 'localhost', 'port': addr.port, 'path': '/speech', 'method': 'POST' }); // now pipe the read stream to the request readStream.pipe(request).on('finish', function() { console.log("pipe end>>>>>>>>>>>>>>>>>>>>>>"); }); // get the response and finish when we get all the response data request.on('response', function(response) { console.log("request end>>>>>>>>>>>>>>>>>>>>>>"); response.on('data', function(data) { console.log('response data: ' + data); }); response.on('end', function(data) { console.log('done!'); done(); }); }); }); });
I think the code should be clear, I just use the standard node http module to do the job.