javascripttypescriptexpressjestjssupertest

Supertest+Jest does not send JSON payload


Here is my test function :

describe("Create a problem", () => {
    describe("Create a problem with valid data", () => {
      it("Should 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 of jest is -

> express-ts@1.0.0 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
    Create a problem
      Create a problem with valid data
        ✕ Should create a problem (79 ms)

  ● Problems › Create a problem › Create a problem with valid data › Should create a problem

    expected { message: 'Problem created.' } response body, got {
      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'"
      ]
    }

As you can see, I have console logged the payload before sending it. I manually sent the console logged payload with Postman, and it worked. But for some reason, it is not working from supertest.

The field-empty errors come from Ajv validator middleware. The code for the validator is below -

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 also console logged the req.body on the validator function. it was empty.

Can anyone tell me why supertest is not sending the payload?


Solution

  • According to jonrsharpe's comment, adding .set("Content-type", "application/json") did the trick.