How to test middleware that accepts parameters?
P粉548512637
P粉548512637 2023-09-07 18:39:45
0
1
597

I have the following middleware:

function check(expectedKeys: string[], req: Request): boolean{
  if (expectedKeys.length !== Object.keys(req.body).length) return false;

  for (const key of expectedKeys) {
    if (!(key in req.body)) return false;
  }

  return true;
}

export default function checkRequestBodyKeys(expectedKeys: string[]) {
  return (req: Request, res: Response, next: NextFunction) => {
    const isValid = check(expectedKeys, req);

    if (isValid) return next();
    
    return res.status(Status.BadRequest).json({status: Status.BadRequest, error: ErrorMessage.InvalidRequestBody});
  }
}

I call it like this:

import { Router } from "express";
import postAuth from "../controllers/auth.controller";
import checkRequestBodyKeys from "../middlewares/checkRequestBodyKeys.middleware"

export const authRoute = Router();

authRoute.post("/", checkRequestBodyKeys(["email", "password"]), postAuth);

I want to test whether it returns the expected values ​​(parameters of res and next). I know how to test and mock functions of simple middleware, but for this type I don't know how to implement it.

I'm trying to write code like this, but I know it doesn't make any sense:

describe("validateRequestBody middleware", () => {
  let mockRequest: Partial<Request>;
  let mockResponse: Partial<Response>;
  let nextFunction: NextFunction = jest.fn();

  beforeEach(() => {
    mockRequest = {};
    mockResponse = {
      status: jest.fn().mockReturnThis(),
      json: jest.fn(),
    };
  });

  test('short name should return error', async () => {
    const expectedResponse = [{error: "Invalid name"}];
    mockRequest = {
      body: {
        name: "aa",
        email: "test@yahoo.com",
        password: "###!!!AAAbbb111222"
      }
    }

    const check = checkRequestBodyKeys(
      ["name", "email", "password"]
    );

    expect( checkRequestBodyKeys(["name", "email", "password"]) ).toEqual(Function)
  });
});

Can someone help me solve this problem?

P粉548512637
P粉548512637

reply all(1)
P粉745412116

checkRequestBodyKeys returns a function that is the actual middleware used by express. The returned function must be executed using simulated req, res and next. You can then check whether they, or functions within them, were called with the arguments you expected.

describe("validateRequestBody middleware", () => {
  let mockRequest: Partial;
  let mockResponse: Partial;
  let nextFunction: NextFunction = jest.fn();

  beforeEach(() => {
    mockRequest = {};
    mockResponse = {
      status: jest.fn().mockReturnThis(),
      json: jest.fn(),
    };
  });

  test('short name should return error', async () => {
    const expectedResponse = {status: 400, error: "Invalid name"};
    mockRequest = {
      body: {
        name: "aa",
        email: "test@yahoo.com",
        password: "###!!!AAAbbb111222"
      }
    }

    const check = checkRequestBodyKeys(
      ["name", "email", "password"]
    );

    expect( check ).toEqual( expect.any(Function) )

    // The middleware is called
    check(mockRequest, mockResponse, nextFunction)
    // And here you check if the res.json function was called with certain parameters
    expect( mockResponse.json ).toBeCalledWith(expectedResponse)
  });
});
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template