Converting JSON POST data in Mocha test for an Express application

When I run my Express code from Postman, everything works perfectly. However, when I try to call it from Mocha, I encounter issues specifically with setting data in the header of a POST request. This problem only occurs with POST requests containing parameters, as GET and parameterless POST requests function as expected.

Below is the simplified code snippet that functions correctly in 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 is the example of 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 is the excerpt showing how it's handled in 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.

I'm seeking assistance in identifying where I am going wrong or even tips on how to troubleshoot this issue?

Answer №1

Embrace contemporary JavaScript!

You could delve into the world of fetch, which is the modern equivalent in ES5 and utilizes Promises for smoother handling. It offers improved readability and flexibility.

const fetch = require("node-fetch");

const term1 = 'hubris'; // Avoid reserved words like object
const term2 = 'pervasive';
let parameters = {'first': term1,
                                'second': term2};
const endpoint = "http://example.com";
fetch(endpoint, {
    method : "POST",
    body: parameters,
    // -- 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();
);

Answer №2

To fix the issue, make sure to capitalize the "T" in "Type" like so:

xhttp.setRequestHeader("Content-Type", "application/json");

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble making alerts or confirmation dialogs function in JavaScript

EDIT: Many thanks to everyone who helped fix this issue (: Your help is greatly appreciated! I've been struggling to get the alert, confirm, or prompt functions to work properly in my code. Here's a snippet of the code that's causing troubl ...

Vue.js template is failing to properly render hyperlinks, although basic string output is functioning as expected

Whenever I print attrib.link, everything works perfectly fine, <div v-for="attrib in attributes"> {{ attrib.link }} </div> However, when I try: <div v-for="attrib in attributes"> <a target='_blank' href={{ attrib.link } ...

Issue encountered while attempting to save hook arrays: Uncaught TypeError - 'choices' is not able to be

I'm in the process of creating a straightforward multiple-choice exam form that includes choices and answers. Whenever a user selects an option, it should be added to the array of choices. At the start, I have an array called exercises, which consist ...

Ways to update a component from another in React

My React code includes an Employees page that renders both a Table component and a Filter component. The Filter component manipulates some data stored in the Employees page, updates the Filter's state through useEffect, and passes the data as a prop t ...

Using Node.js and Express to upload a file seamlessly without needing to refresh the page

I'm in the process of developing a chat application with Node.js and I want to incorporate a file upload feature. However, every time I upload a file, the browser redirects to another link or refreshes the page, which disrupts the flow of the chat. I ...

Unable to assign headers once they have already been sent to the recipient - a Node.js error

Encountering an error message stating "Cannot set headers after they are sent to the client." I've researched and it seems like multiple callbacks may be causing this issue. However, I'm struggling to find a solution. Any assistance in resolving ...

"Troubleshooting why React fails to update an array state

When I click the update name button, the state is not changing properly using setState. I want to update the persons variable and have it reflect in the DOM as well. Any ideas on how to achieve this? App.js import React, { Component } from "react"; impo ...

Is there a way to extract the timestamp in JavaScript from a string that includes the name of the timezone database?

Given the string: "2022/05/01 03:10:00", I am seeking to create a Date object with Chile's UTC offset. The challenge lies in the fact that due to Daylight saving time (DST), the offset changes twice annually. How can I obtain that Date obj ...

The cookie seems to have mysteriously vanished, despite being included in the response headers. Our investigation points to the use

Issue: I am facing a problem while trying to set the cookie on login using express-session. Even though the response to the login POST request includes Set-Cookie, there seems to be an issue. I have ensured that Access-Control-Allow-Origin and Access-Cont ...

Utilizing the map() function to parse a Json object

Looking for guidance with working with a JSON object structured like this: {"Title":"asb","Date":"2019","Other":"not important"} How can I correctly read this object and render it in <ul><li> format? Please Note: I have attempted to assign th ...

Error message in console: React Form showing "Form submission canceled due to lack of connection" despite successful submission

I am facing an issue with my form in my React app. Even though the form is successfully submitting data to a list of boxes, I received an error in the console. The error message says: Form submission canceled because the form is not connected In my Rea ...

The function user.setPassword is not available at this time (While resetting password)

My express app uses passport for user authentication, which is working fine. However, I am facing an issue while trying to implement a password reset feature. The error message I receive is: TypeError: user.setPassword is not a function I have researched ...

What would be the best way to create a JavaScript function that emulates the functionality of an Upgrade Button?

I am currently working on developing a clicker game and have reached the point where I need to implement a function for the 'upgrade click' button. This function should deduct a certain amount of money when clicked, while also increasing the amou ...

Steps to generate an error in the 'response' function of a $httpProvider interceptor

I am currently working on creating a custom HTTP interceptor in Angular and I am looking to generate an error from the response of the $httpProvider interceptor. According to the provided documentation: response: Interceptors are triggered by the http re ...

Ways to attach dynamic methods within a v-for loop

I am currently working on a situation where I need to dynamically assign methods to elements that are being generated by a template using a v-for loop. These methods will be assigned based on the value of a particular variable, specifically the 'btn.m ...

Interactive tables created using Google Visualization

I have a Google visualization data table that works well, but I am facing an issue with the width of the table. When I click as shown in the image, I call the function drawTable(); and then I encounter this: As you can see, the table does not have a width ...

Sharing models between AngularJS controllers

I am currently in the process of developing an application that will showcase various charts and controls to filter the presented data. I have structured the HTML page in a way that remains consistent throughout, leading me to consider creating an HTML tem ...

Using JavaScript to place markers on a Google Map may encounter an issue with a for

Close to solving a three-day challenge. Currently working on placing markers on a Google Map using latitudes and longitudes stored in a Django model. This is my first time using AJAX, but I'm giving it a shot to make this work. Firebug is pointing out ...

Autocomplete's `getOptionLabel` function unexpectedly returned an object ([object Object]) instead of the expected string

Currently delving into the world of ReactJS and working with @mui controls, specifically a Multiselect Dropdown with autocomplete feature. Here is the child component causing me some trouble, displaying the following error message: "index.js:1 Materi ...

Ways to dynamically update a Vuetify 3 element's placeholder text?

Here is the code snippet from my component.vue file: <template> <v-text-field name="Foo" :label="$t('foo')" type="text" hint="This is a hint" persistent-hint >& ...