My NodeJS Express code runs just fine when called from Postman, but not when called from Mocha. This leads me to believe that my Mocha test is not correctly setting the data in the header of a POST request (I have no problem with paramaterless GET or POST, not with GET with parameters; only with POST with parameters.
Here's the simple code, although I would not concentrate on this, as it works from Postman:
const app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Our unit tests send POST data in JSON format
app.use(express.json());
// Helper function - common code
function ResplyWithSentence(object, adjective)
{
console.log('GET requestuest received: object = ' object '; adjective = ' adjective);
let sentence = softwareUnderTest.MakeAsentence(object, adjective);
sentence = JSON.stringify(sentence);
response.status(200);
response.set('Content-Type', 'text/json');
response.send( sentence );
}
// Handling POST request with parameters
app.post("/makeSentenceParamsPost", (request, response) => {
const object = request.body.object;
const adjective = request.body.adjective;
ResplyWithSentence(object, adjective);
})
Here's what Postman sends:
POST /makeSentenceParamsPost HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
Postman-Token: 88dfc7cc-427e-3248-ba93-286083d4c18d
{
"object": "cat",
"adjective": "sleepy"
}
and here's the Mocha:
it('should handle a POST request with parameters', async function(){
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://localhost:3000/makeSentenceParamsPost", false); // false === synchronous/blocking
xhttp.setRequestHeader("Content-type", "application/json");
const object = 'hubris';
const adjective = 'pervasive';
let postParameters = {'object': object,
'adjective': adjective};
xhttp.onreadystatechange = function(done) {
while(this.readyState != 4) ; // wait until "request finished and response is ready"
assert.isObject(this);
assert(this.status == 200);
assert(JSON.parse(this.responseText)['sentence'] == `The ${object} is ${adjective}`);
done();
};
postParameters = JSON.stringify(postParameters);
xhttp.send(postParameters);
});
The response received is The undefined is undefined.
Can anyone tell me what I am doing wrongly? Or even how to debug this?
CodePudding user response:
Use modern JavaScript!
I'd suggest looking into fetch. It is the ES5 equivalent and uses Promises. It is much more readable and easily customizable.
const fetch = require("node-fetch");
const first = 'hubris'; // can't use words like object, these are reserved.
const second = 'pervasive';
let postParameters = {'first': first,
'second': second};
const url = "http://example.com";
fetch(url, {
method : "POST",
body: postParameters,
// -- or --
// body : JSON.stringify({
// user : document.getElementById('user').value,
// ...
// })
}).then(
response => response.text() // .json(), etc.
assert.isObject(this);
assert(this.status == 200);
assert(JSON.parse(this.responseText)['sentence'] == `The ${object} is ${adjective}`);
done();
);
CodePudding user response:
D'oh!!! I a an imbicile :-(
xhttp.setRequestHeader("Content-type", "application/json");
upper case T on Type solves the problem
xhttp.setRequestHeader("Content-Type", "application/json");