search

Home  >  Q&A  >  body text

How to test middleware that accepts parameters?

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粉548512637P粉548512637489 days ago617

reply all(1)I'll reply

  • P粉745412116

    P粉7454121162023-09-08 13:03:29

    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)
      });
    });

    reply
    0
  • Cancelreply