I am using Jest to unit test my routes for a controller for an express API. The controller route calls validationResult(req)
, however, when I run the jest test the validationResult comes back empty. How does one unit test express-validator?
Controller:
import { Request, Response, NextFunction } from "express";
import { validationResult } from "express-validator";
import TDS from "../DomainLogic/TasmanianDevilService";
async function createTasmanianDevil (
req: Request,
res: Response,
) {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json(errors.array());
}
console.log(errors);
const result = await TDS.createTasmanianDevilAsync(req.body.{attribute});
if(result === undefined) {
return res.status(500).json('Error');
}
return res.status(200).json(
result
);
};
export default { createTasmanianDevil };
Validator:
import express from "express";
import controller from "../controllers/TasmanianDevilController";
import { check, body, query } from "express-validator"
const router = express.Router();
router.post('/createTasmanianDevil', [
body({attribute}).isInt(),
], controller.createTasmanianDevil);
export = router;
Jest Test:
import TDC from "../../controllers/TasmanianDevilController";
import TDS from "../../DomainLogic/TasmanianDevilService";
import { getMockReq, getMockRes } from "@jest-mock/express";
jest.mock("../../DomainLogic/TasmanianDevilService");
describe("createTasmanianDevil", () => {
let req = getMockReq();
const { res, mockClear } = getMockRes();
beforeEach(() => {
TDS.createTasmanianDevilAsync = jest.fn().mockReturnValue(0);
mockClear();
});
test("should validate {attribute} must be number", async () => {
req.body.{attribute} = "not a number"
await TDC.createTasmanianDevil(req, res);
expect(res.status).toHaveBeenCalledWith(400);
});
});
To test the express route including the validation middleware functionality, you should send a real HTTP request against your app. The SuperTest npm module lets you easily test HTTP requests against your routes. Once you have the SuperTest npm module installed you can test the express-validator
logic like so:
import request from "supertest";
import app from "./app.js";
test("should validate the attribute", async () => {
const response = await request(app)
.post("/createTasmanianDevil")
.send({ attribute: "non-number" })
expect(response.status)
.toEqual(400);
expect(response.body)
.toEqual([{
location: "body",
msg: "Invalid value",
param: "attribute"
}]);
});
See the Getting Started docs for more info.