This one has me stumped. I'm using mochajs as a test suite for a NodeJS (Express 4) application. The test suite runs through a series of mocha files, all using a pretty similar set up,and when run individually they all run fine - but when run as a suite, one file suddenly fails with the error:
TypeError: request.defaults is not a function
at Object.module.exports.apiName (/my/system/file/path/repo/lib/reports.js:176:30)
All the files used to work, even when run as a suite, but we recently switched from using to use a config.json file as the environment determinant to using process.env.NODE_ENV
- not sure if its related but the timing lines up.
A simplified overview of the file chain would look something like:
command line call:
env NODE_ENV=local mocha test
...runs through file1, file2, file3, etc until:
test/reports.js
var env = process.env.NODE_ENV,
config = require('../config.json');
// Libraries
var app = require('../app'), // Imports the application
http = require('http'), // Sets up the test server on a different port
assert = require('assert'), // Checks values against expected
request = require('supertest'); // Tests API Calls - https://www.npmjs.com/package/supertest
describe.skip('Reports', function() {
before(function(){
// Start APP and expose on a test different port
this.server = http.createServer(app).listen(3000);
// Set request path to server - needs to match above
request = request('http://localhost:3000');
});
describe('#NameOfAPI', function(){
it('should return {status:"error"} if invalid report requested (Requires Mongo Running)', function(done) {
this.slow(300);
request
.get('/app/reports/api/nameOfAPI?report=invalidReportName')
.expect(200)
.expect('Content-Type', /json/)
.end(function(err, res){
it(res.body)
assert.equal(null, err); // Ensure no errors in request
assert.equal('error', res.body.status); // Ensure correct status returned for invalid data
assert.notEqual(-1, res.body.messages[1].search(/empty response/i)); // Ensure proper message returned for invalid report
done();
}); // End HTTP request for invalid report
}); // End Test for invalid report
});
The request (via supertest) obviously calls the route (app/reports/api)->API (nameOfAPI) module:
lib/reports.js
var env = process.env.NODE_ENV,
config = require('../config.json'),
request = require('request');
var module.exports = {
requestReportToCsv: function(report_name, hostname, cb){
var req_limit = 100; // Set maximum concurrent requests - server returning numerous 'ECONNRESET' errors if hit too fast
// Set HTTP request defaults outside of any loops
// THIS IS THE LINE THAT'S FAILING - lib/reports.js:176:30
var http_request = request.defaults({ json: true, pool: { maxSockets: req_limit } });
if (env != 'prod') {
http_request = http_request.defaults({headers: {'dev-cookie': 'on', 'Cookie':'dev_cookie=on'}});
}
http_request.post('https://website.com/api/info.php', {form: post_data}, function(err, resp, body){
// Uncomment to see an example of the report response
...SO ON AND SO FORTH
Can't for the life of me figure out why request.defaults({})
will work fine when the mocha test file is called individually using env NODE_ENV=local mocha test/reports
but fail when run as part of a suite using env NODE_ENV=local mocha test
. Any ideas?
Edit: Note, renaming the var request = require('supertest')
variable var supertest = require('supertest')
(and all subsequent references) doesn't have an effect, so I don't think it's a scope/variable/name issue.