Supertest and Jest do not allow for sending JSON payloads between requests

Below is the test function I have written:

describe("Test to Create a Problem", () => {
    describe("Create a problem with valid input data", () => {
      it("Should successfully create a problem", async () => {
        const ProblemData = {
          title: "Pothole on Main Street",
          type: 2,
          description: "Large pothole on Main Street that is causing damage to vehicles",
          district: "Downtown",
          coordinates: "42.3584,-71.0598",
          address: "123 Main St, Boston, MA",
          photos: JSON.stringify(["pothole1.jpg", "pothole2.jpg"]),
          audio: "potholedowntown.mp4",
        };
        const payload = JSON.stringify(ProblemData);
        console.log(payload);

        await supertest(app)
          .post(`/problems/create`)
          .send(payload)
          .expect(400)
          .expect({
            message: "Problem created."
          });
      });
    });
});

The output from Jest is as follows:

> [email protected] test
> jest

  console.log
    {"title":"Pothole on Main Street","type":2,"description":"Large pothole on Main Street that is causing damage to vehicles","district":"Downtown","coordinates":"42.3584,-71.0598","address":"123 Main St, Boston, MA","photos":["photo1.jpg","photo2.jpg"],"audio":"potholedowntown.mp4"}

      at src/tests/Problems.test.ts:60:17

 FAIL  src/tests/Problems.test.ts
  Problems
    Test to Create a Problem
      Create a problem with valid input data
        ✕ Should successfully create a problem (79 ms)

  ● Problems › Test to Create a Problem › Create a problem with valid input data › Should successfully create a problem

    expected { message: 'Problem created.' } response body, received {
      message: 'Invalid request body.',
      errors: [
        "must have required property 'title'",
        "must have required property 'description'",
        "must have required property 'type'",
        "must have required property 'district'",
        "must have required property 'address'",
        "must have required property 'coordinates'",
        "must have required property 'audio'",
        "must have required property 'photos'"
      ]
    }

In the above code snippet, you can see that I logged the payload before sending it out. Strangely, when tested using Supertest, it does not work as expected.

The empty-field errors are due to the Ajv validator middleware. Here is the code snippet for the validator function:

export default function Validator(schema: object) {
  return async (req: Request, res: Response, next: NextFunction) => {
    let valid: boolean = false;
    try {
      valid = ajv.validate(schema, req.body);
    } catch (err) {
      Logger("FILE : Validator.ts \n" + String(err));
      res.status(500).json({ message: "Internal Server Error" });
      return;
    }
    if (!valid) {
      let errors = ajv.errors;
      let errMessages: (string | undefined)[] = [];
      if (errors) {
        errMessages = errors.map((error) => {
          return error.message;
        });
      }
      return res.status(400).json({
        message: "Invalid request body.",
        errors: errMessages
      });
    }
    next();
  };
}

I even logged the req.body in the validator function and found it to be empty. Can someone explain why Supertest is failing to send the payload?

Answer №1

Based on the feedback from jonrsharpe, including

.set("Content-type", "application/json")
solved the issue.

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

Modifying the order of Vuetify CSS in webpack build process

While developing a web app using Vue (3.1.3) and Vuetify (1.3.8), everything appeared to be working fine initially. However, when I proceeded with the production build, I noticed that Vue was somehow changing the order of CSS. The issue specifically revol ...

The functionality of jQuery smooth scrolling to an anchor is only effective when the page is at the top and there is

Currently, I am working on designing a simple one-page website featuring a fixed menu that smoothly scrolls to specific sections on the page upon clicking the menu items. However, I have encountered an issue where the scrolling works perfectly only when t ...

Tips for formatting numerical output in EJS by rounding the value

I am displaying a value in EJS and I am looking to format it to show fewer decimal places. This is related to the EJS engine on the frontend. Value displayed: 4.333333333333333 I want it to be displayed like this: 4.3 The EJS code snippet used: <p cl ...

What is the reason for my Firestore listener consistently retrieving data from the server despite having offline persistence enabled?

Incorporating Firebase JavaScript Modular Web Version 9 SDK into my Vue 3 / TypeScript application. My understanding is that when utilizing real-time listeners with offline persistence in Firestore, the process should proceed as follows: Upon initializat ...

retrieving information from the database and passing it to the controller

I'm in the process of developing a new API with Express, following the MVC architecture. However, I've been facing difficulties getting the data to successfully return from the database access file to the controllers file. Initially, I attempted ...

Using query parameters in Angular to interact with APIs

One scenario involves a child component passing form field data to a parent component after a button press. The challenge arises when needing to pass these fields as query parameters to an API endpoint API GET /valuation/, where approximately 20 optional p ...

Utilizing node.js, mongoDB, and express.js to upload and recover images

Is there a way to upload an image from my browser and save it as a local file while also adding the file name to mongodb? I want to be able to retrieve the stored file in the local folder and display it in the browser. Thank you, Babji ...

What is the best way to store user input in local storage using Vue.js?

Following the official Vue.js site, I have been trying to implement Framework 7. However, when using an input field, [object InputEvent] is displayed both when typing text and attempting to save it. Is there a way to store a name in local storage and have ...

Keep the link underlined until a different button is pressed

I need help with a webpage that displays a list of partners organized by categories. When clicking on sidebar categories, the link remains underlined. However, if you click anywhere else on the page, the link becomes inactive. CSS: button:hover { t ...

What is the process for transferring an environment.json file to the output directory and then utilizing it with Webpack 4?

Our application is expanding with multiple environments and vendors on the horizon. While the traditional approach of running webpack --env.NODE_ENV=myenvironment works for now, it will soon become inefficient. The main objective here is to streamline the ...

Obtain value of dropdown selection upon change

What is the best way to retrieve the selected value in a drop-down menu when the ID dynamically changes with each refresh? Is it possible to access the particular selected value even when the ID changes? <select name="status" id="dropdown_status3352815 ...

Automatically close Bootstrap 4 modal popups

I am using Bootstrap 4 and trying to make my modal automatically close after 3 seconds. I attempted a solution but it seems to not be functioning correctly. The modal itself works fine, but the auto-closing feature is not working as expected. Below is the ...

Is there a way to conceal a div class on the Payment page in Shopify?

I have encountered an issue with the code on the Shopify checkout (Payment) Page. Unfortunately, I am unable to directly edit this page within Shopify, but I have discovered that it is possible to add custom CSS or HTML code within the checkout settings of ...

Docusaurus font loading specifically optimized for body text, excluding headings

I've added the following CSS code to my Docusaurus custom stylesheet: @import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap"); :root { --ifm-color- ...

Content within the Grouped Bar Graph Bar D3.js

I referred to https://bl.ocks.org/mbostock/3887051 and customized the bar chart by adding text inside each bar representing a count, such as Upstream is 50, so the number 50 should appear in the bar itself. Despite trying solutions from resources like D3. ...

Employing DOM manipulation within Vue unit tests as a last resort

What steps should I take to update my unit test in order to accurately validate the following scenario? Method: close(event) { const element = !!event?.target?.closest('#target') if (!element) { this.isVisible = false } }, Jest test: ...

Integration of Mocha with WebStorm

WebStorm offers a useful feature that adds a small arrow next to describe() and it() keywords when writing tests with Mocha, allowing for easy manual execution. However, there is a challenge: I require additional setup before each test, leading me to use ...

Tips on ensuring that the Angular frontend waits for the response from an Express REST call

Upon initializing my user Component, I want to trigger a REST-Call so that the user profile is displayed when the page loads. The process works smoothly as the component communicates with the service, which in turn contacts my express backend to make the n ...

Utilizing Async and await for transferring data between components

I currently have 2 components and 1 service file. The **Component** is where I need the response to be displayed. My goal is to call a function from the Master component in Component 1 and receive the response back in the Master component. My concern lies ...

the undefined 'pipe' cannot be read

Trying to perform unit testing for an Angular component is a new experience for me. Currently, I am encountering a specific issue that I would like assistance with. The component in question contains the following select statement: this.store.select(getI ...